一次简单的问题排查背后蕴含的巨大的知识量
现象
- 所有的请求都卡住。
- 堆dump正常。
- 有一段时间内存占用高,GC频繁且耗时长,过了那段时间后监控上恢复正常。
- 日志有OutOfMemory的异常
结论
在这段代码OOM之前,它会导致JVM不停 fullGC 与 stopWorld,从而导致了程序卡死。(这也是为什么那一天的上午日志中并没有OOM,但是请求却也被卡住)
在这段OOM之后,之前由于它的不停的挤占空间,而它每次又只申请一小块内存,因此导致一些申请稍大内存的地方提前爆出如上的OOM异常。因此即使最后的问题代码OOM了,所占用的内存被回收掉了,但是由于一些重要线程挂了,依然会导致请求无法被处理。
如果线程的异常没有被捕获,那么JVM会在线程终结前打印日志,该日志会打印到标准流(service_stdout)中去,如下(这么多重要线程都挂了)
为什么操作系统显示进程占用内存很多,但是堆dump却只有600M的大小
原因
连续大片内存,回收时,JVM会还给操作系统,通过brk移动指针就可以办到。(malloc如果要向操作系统申请内存时,将brk指针向上移动,free如果要向操作系统归还内存时,将brk向下移动,这意味着,它必须归还最上面的连续内存)
但是如果是很多的小的内存碎片,JVM不会还给操作系统,因为通过移动brk指针不能办到。
- linux内核分页与Buddy:
- https://www.cnblogs.com/theseventhson/p/15703182.html
- linux内存分配(C语言与系统调用):
- https://blog.csdn.net/TABE_/article/details/123098479
- https://cloud.tencent.com/developer/article/1420726
- JVM物理内存不释放:
- https://cloud.tencent.com/developer/article/1912171
如下代码,发现以前占用的小内存JVM没有还给操作系统,即使已经被垃圾回收了:
操作系统显示一直保持这个值不变,但是GC日志显示已经回收了。
测试代码:
import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;public class Main {public static volatile boolean shouldEnd = false;public static void main(String[] args) throws InterruptedException {for (int i = 0; i < 2; i++) {new Thread(() -> {try {System.out.println("Loop Thread start");List<LocalDate> array = new ArrayList<>();while (!shouldEnd) {LocalDate localDate = LocalDate.now();array.add(localDate);}System.out.println("Loop Thread end");} catch (Throwable e) {System.out.println("Thread end");e.printStackTrace();}}).start();}while (true) {try {if (!shouldEnd) {Thread.sleep(10 * 1000);} else {Thread.sleep(1000);}byte[] arrays = new byte[512 * 1024 * 1024];System.out.println("Clock get big area!");} catch (Throwable e) {shouldEnd = true;e.printStackTrace();}}}
}
收获
- 不要死循环
- try catch 的时候尽量去catch Throwable,而不是Exception,这样即使OutOfMemeoy的时候,也能捕获到这个异常。当然像上面这个问题,即使去申请一个稍微大一点的数据,也可能导致自己的线程OOM,我们的代码不可能每一行都在 try catch 范围中。
一次简单的问题排查背后蕴含的巨大的知识量相关推荐
- 【摩客专访】简单易用的背后是吹毛求疵的追求 | 专访“方片收集”作者田飞
采访者:做原型更快更简单的Mockplus 企划经理 Martin 受访者:"方片收集"作者田飞先生及其团队 本期"摩客专访"我们非常荣幸邀请到了"方 ...
- 简单探寻GCC编译器背后的故事
目录 一.用gcc生成 .a静态库和 .so动态库 1.编辑生成例子程序 2.将hello.c编译成 .o文件 3.由 .o文件创建静态库 4.在程序中使用静态库 5.由.o 文件创建动态库文件 6. ...
- 《糖豆人:终极淘汰赛》成功背后蕴含了何种设计?
「别推我!别抓我的尾巴,你们这群糖豆人滚啊!」 你在玩<糖豆人>时,嘴里十有八九会不由自主地说出这些话.数十个五彩缤纷的糖豆人相互推攘,紧抓对方肢体的景象已经席卷了整个游戏界. 自 8 月 ...
- 深富策略:罕见巨额成交量背后蕴含深意
回顾周二A股行情,沪深两市小幅低开,盘初股指分化,随后沪指继续拉高,而深成指红盘上方窄幅整理.午后三大股指全线拉升,沪指走强中已经逼近年初高点,而深成指半年线附近迎来连续反弹,创业板指涨势稍弱.从盘面 ...
- 《数字中国建设整体布局规划》出炉,背后蕴含的数字城市巨大机遇
近年来,数字经济的快速发展成为中国实现高质量发展的关键引擎.随着5G.云计算.人工智能等技术的飞速发展,数字经济正成为拉动中国经济增长的新动力.为了推动数字经济发展,日前发布<数字中国建设整体布 ...
- 音视频技术开发周刊 88期
『音视频技术开发周刊』由LiveVideoStack团队出品,专注在音视频技术领域,纵览相关技术领域的干货和新闻投稿,每周一期.点击『阅读原文』,浏览第88期内容,祝您阅读愉快. 架构 思科:2022 ...
- hihocoder第226周:打表找规律
题目列表 问题描述 有一个文本框,可以执行以下操作: 输入A Ctrl+C 复制 Ctrl+V 粘贴 Ctrl+A 全选 N次操作最多能够造出多少个A来? 输入一个N,输出一个整数,表示最多有多少个A ...
- 机器学习中的编码器-解码器结构哲学
其它机器学习.深度学习算法的全面系统讲解可以阅读<机器学习-原理.算法与应用>,清华大学出版社,雷明著,由SIGAI公众号作者倾力打造. 书的购买链接 书的勘误,优化,源代码资源 本文PD ...
- cache 访问延迟背后的计算机原理
简介:本文介绍如何测试多级 cache 的访存延迟,以及背后蕴含的计算机原理. CPU 的 cache 往往是分多级的金字塔模型,L1 最靠近 CPU,访问延迟最小,但 cache 的容量也最小.本文 ...
最新文章
- Python通过一个网页地址获得网页标题Title
- 推荐一位大佬,在腾讯工作十年
- 用 PS 调整服务器时间
- python docx 合并文档 图片_不再为处理PDF烦恼,python处理操作PDF全攻略
- Spring 拦截器和过滤器中自动注入为 null 的原因及解决方案
- c++如何禁用指定的键盘布局_Karabiner Elements for Mac 键盘键位自定义改键工具
- python 扫描仪_基于Opencv和Python的多选扫描仪
- 【Recat 应用】之 React 脚手架
- jquery click()方法模拟点击事件对a标签不生效的解决办法
- 选择数据分析工具应考虑4个因素
- CART树算法的剪枝算法
- Excel中插入图表后在设计选项卡无法选择样式解决办法
- openvpn部署和迁移
- 操作——【1.8 关于音高、时值、位置 】(二)
- 如何使用poi解析word生成html目录结构
- java FTP连接时出现“227 Entering Passive Mode”的解决方法
- strace命令用法详解
- 5.4 文本分析与加密
- oracle 数据字典画报,收藏!Oracle常用数据字典表、视图的总结,都在这里了
- 黑帽大会:黑客把入侵汽车当兴趣
热门文章
- python汽车招聘_【一点资讯】C/C++和Python在无人驾驶汽车招聘信息中位居热门技能冠亚! www.yidianzixun.com...
- scala语法 -多维数组
- 拔智齿过程的RAP现象
- 网络算法系列之社区发现(一):标签传播算法
- matlab实现拨号音识别
- 2014年5月最后一周工作总结
- 远鉴科技“语音识别”技术获美亚柏科青睐!
- 用PS制作256色的BMP图片
- L1X-2 矩阵转置 (10 分)
- Tarjan算法求割点与割边(python3实现)