给我1万字,也讲Java不清内存排查。1万不行来2万~.
why?因为内存溢出是Java码农永远的伤 。
溢出有很多种解释 , 有精满自溢 , 有缓冲区溢出攻击 , 还有另外一种叫做领导的溢出 。 不知道什么叫作溢出理论 , xjjdog在此普及一下 。
《领导看了会炸毛的溢出理论》
内存溢出什么最重要?其实 , 内存溢出就像是一场交通事故 。 事故的发生方 , 就是具体的服务;事故的处理方 , 就是相关的程序员 。 其中有一个最重要的环节 , 就是在事故现场需要拍照取证 。
如果没有照片没有行车记录仪没有证据 , 就只能靠那张嘴 , 怎么说都是不可信的 。
**这句话很重要很重要:内存问题排查什么最重要?当然是信息收集 , 留下一些为我们的排查提供支持的依据 。 **千万不要舍本逐末 , 对内存问题排查本身感兴趣 , 那是自虐行为 。
有很多工具可以帮助我们定位问题 , 但前提是你得把它留下来 。 下面这篇文章是xjjdog很久之前留下来的 , 由于标题的缘故 , 你可能忽略了 , 但这些工具能够快速帮我们定位问题 。
《将java进程转移到“解剖台”之前 , 法医都干了什么?》
【给我1万字,也讲Java不清内存排查。1万不行来2万~.】很多同学上来就说 , 我的内存溢出了 。 但你和它要一些日志信息 , 要堆栈 , 要现场保存的快照 。 都没有 。 这就是纯粹来搞笑的 。
下面是JDK8或者以下的GC日志参数 , 可以看到还是很长的 。
#!/bin/shLOG_DIR="/tmp/logs"JAVA_OPT_LOG="-verbose:gc"JAVA_OPT_LOG="${JAVA_OPT_LOG}-XX:+PrintGCDetails"JAVA_OPT_LOG="${JAVA_OPT_LOG}-XX:+PrintGCDateStamps"JAVA_OPT_LOG="${JAVA_OPT_LOG}-XX:+PrintGCApplicationStoppedTime"JAVA_OPT_LOG="${JAVA_OPT_LOG}-XX:+PrintTenuringDistribution"JAVA_OPT_LOG="${JAVA_OPT_LOG}-Xloggc:${LOG_DIR}/gc_%p.log"JAVA_OPT_OOM="-XX:+HeapDumpOnOutOfMemoryError-XX:HeapDumpPath=${LOG_DIR}-XX:ErrorFile=${LOG_DIR}/hs_error_pid%p.log"JAVA_OPT="${JAVA_OPT_LOG}${JAVA_OPT_OOM}"JAVA_OPT="${JAVA_OPT}-XX:-OmitStackTraceInFastThrow"下面是JDK9及其以上的日志配置 。 可以看到它的配置方式全变了 , 而且不向下兼容 。 Java搞的这个变化还是挺蛋疼的 。
#!/bin/shLOG_DIR="/tmp/logs"JAVA_OPT_LOG="-verbose:gc"JAVA_OPT_LOG="${JAVA_OPT_LOG}-Xlog:gc,gc+ref=debug,gc+heap=debug,gc+age=trace:file=${LOG_DIR}/gc_%p.log:tags,uptime,time,level"JAVA_OPT_LOG="${JAVA_OPT_LOG}-Xlog:safepoint:file=${LOG_DIR}/safepoint_%p.log:tags,uptime,time,level"JAVA_OPT_OOM="-XX:+HeapDumpOnOutOfMemoryError-XX:HeapDumpPath=${LOG_DIR}-XX:ErrorFile=${LOG_DIR}/hs_error_pid%p.log"JAVA_OPT="${JAVA_OPT_LOG}${JAVA_OPT_OOM}"JAVA_OPT="${JAVA_OPT}-XX:-OmitStackTraceInFastThrow"echo$JAVA_OPT一旦发现了问题 , 就可以拿GC日志来快速定位堆内问题 。 但是并不是让你一行行去看 , 那太低效了 。 因为日志可能会很长很长 , 而且也不一定看得懂 。 这个时候 , 就可以使用一些在线工具辅助解决 。 我经常使用的是gceasy , 下面是它的一张截图 。
jmap-dump:format=b,file=heap.bin37340jhsdbjmap--binaryheap--pid37340MAT工具是基于eclipse平台开发的 , 本身是一个Java程序 。 分析HeapDump文件:发现内存创建了大量的报表对象 。
系统存在大数据量查询服务 , 并在内存做合并当并发量达到一定程度 , 会有大量数据堆积到内存进行运算解决方式:
重构查询服务 , 减少查询的字段使用SQL查询代替内存拼接 , 避免对结果集的操作举例:查找两个列表的交集案例分析二现象环境:CentOS7 , JDK1.8 , JBossCMS垃圾回收器操作系统CPU资源耗尽访问任何接口 , 响应都非常的慢分析发现每次GC的效果都特别好 , 但是非常频繁了解到使用了堆内缓存 , 而且设置的容量比较大缓存填充的速度特别快!结论:
开了非常大的缓存 , GC之后迅速占满 , 造成GC频繁案例分析三现象java进程异常退出java进程直接消失没有留下dump文件GC日志正常监控发现死亡时 , 堆内内存占用很少 , 堆内仍有大量剩余空间分析XX:+HeapDumpOnOutOfMemoryError不起作用监控发现操作系统内存持续增加下面这些情况都会造成程序退出而没什么响应 。
被操作系统杀死dmesgoom-killerSystem.exit()javacom.cn.AA&后终端关闭kill-9解决发现:
在dmesg命令中发现确实被oom-kill解决:
给JVM少分配一些内存 , 腾出空间给其他进程案例分析四请参见堆外内存排查这篇文章 。 《Java堆外内存排查小结》
End
推荐阅读
- 美军造船厂罢工一个多月,工人趁势发“国难财”:必须给我加工资
- 脸蛋|如果没有萌萌哒的脸蛋,别给我提什么是时尚~
- 山是山河是河,购车首选欧蓝德,期待它给我带来的惊喜
- |客户电脑R9-3950X处理器坏了直接送给我,一开心我就给他上堂课!
- 别给我夹蘑菇|孙芮snh48大选第一,你不知道的三哥,有趣灵魂下还有美丽的皮囊
- 刘禹锡|遇小人怎么办?刘禹锡用一系列操作和一千古名作,给我们上了一课
- 琉璃红孔雀|“房子租出去,不如给我闺女”,婆婆一心占便宜,不料被反唇相讥
- 非主流|生活带给我的焦虑,都被“非主流”的她们治愈了
- 游戏画质越来越好,带给我的快乐却越来越少,是游戏不好玩了吗?
- 别给我夹蘑菇|王一博街舞新造型,流苏涂鸦紫色外套,帅气难挡,惹人爱!