如何让生产环境的JVM在OOM时自动dump内存快照

举报
JavaEdge 发表于 2022/01/31 23:13:09 2022/01/31
【摘要】 假设知道自己的系统OOM了,咋办? 解决OOM的初步思路OOM必然说明系统中某区的对象太多,塞满那个区,而且一定无法回收掉那些对象,最终才导致内存溢出。就得知道到底是什么对象太多了最终导致OOM,就必须得有一份JVM发生OOM时的dump内存快照。 OOM的时候自动dump假设JVM发生OOM了,你觉得JVM是完全来不及处理然后突然进程就没了吗?也就是JVM是看起来非常突然的自己无法控制的就...

假设知道自己的系统OOM了,咋办?

解决OOM的初步思路

OOM必然说明系统中某区的对象太多,塞满那个区,而且一定无法回收掉那些对象,最终才导致内存溢出。

就得知道到底是什么对象太多了最终导致OOM,就必须得有一份JVM发生OOM时的dump内存快照。

OOM的时候自动dump

假设JVM发生OOM了,你觉得JVM是完全来不及处理然后突然进程就没了吗?也就是JVM是看起来非常突然的自己无法控制的就挂掉了吗?

不是的,JVM本身在发生OOM之前都会尽可能的去进行GC腾出来一些内存空间,如果GC后还是没有空间,放不下对象, 才会触发内存溢出。

所以JVM自己对OOM情况的发生是完全有把控权的,他知道什么时候会触发OOM,也是他自己感觉不行的时候才会去触发。所以OOM的发生并不是大家想的那样,突然之间内存太多了,JVM自己都没反应过来就直接崩溃了,并非如此。因此JVM如果知道要发生OOM了,此时完全可以让他做点事情。

可以让他在OOM时dump一份内存快照,事后我们只要分析这个内存快照,一下就可以知道是哪些可恶的对象占用了所有的内存,并且还无法释放。

此时你就需要在JVM的启动参数中加入如下的一些参数:

# OOM的时候自动dump内存快照出来
-XX:+HeapDumpOnOutOfMemoryError
# 把内存快照放到哪儿去
-XX:HeapDumpPath=/usr/local/app/oom

加入了这两参数,在JVM OOM崩溃的时候,无论你是立马主动收到一个报警,还是被动让客服通知了你,立马就可以去找OOM时候的内存快照了。

JVM参数模板,大家对自己的系统根据情况调整微调即可:

-Xms4096M
-Xmx4096M 
-Xmn3072M 
-Xss1M 
-XX:MetaspaceSize=256M 
-XX:MaxMetaspaceSize=256M 
-XX:+UseParNewGC 
-XX:+UseConcMarkSweepGC 
-XX:CMSInitiatingOccupancyFaction=92 
-XX:+UseCMSCompactAtFullCollection 
-XX:CMSFullGCsBeforeCompaction=0 
-XX:+CMSParallelInitialMarkEnabled 
-XX:+CMSScavengeBeforeRemark 
-XX:+DisableExplicitGC 
-XX:+PrintGCDetails 
-Xloggc:gc.log 
-XX:+HeapDumpOnOutOfMemoryError 
-XX:HeapDumpPath=/usr/local/app/oom
  • 各个内存区域的大小分配,这个是需要你精心调优的
  • 其次是两种垃圾回收器的指定,接着是一些常规性的CMS垃圾回收的参数,可以帮助优化偶尔发生的Full GC性能
  • 最重要的,就是平时要打印出来GC日志,GC日志可以配合你用jstat工具分析GC频率和性能的时候用,jstat可以分析出来GC的频率, 但是对每次具体的GC情况,可以结合GC日志来看
  • 还有就是在OOM的时候需要自动dump内存快照,这样即使突然发生OOM,你只要得知了这个事,立马就可以去分析内存快照了。
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。