1. Open JDK中与OOM有关的参数
-
通过使用如下命令,查看所有的JVM选项的实际值:
java -server -XX:+UnlockExperimentalVMOptions -XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal -version
-
发现Open JDK 8中,与OOM有关的参数如下
-XX:+|-HeapDumpOnOutOfMemoryError -XX:HeapDumpPath -XX:OnOutOfMemoryError -XX:+|-CrashOnOutOfMemoryError -XX:+|-ExitOnOutOfMemoryError
-
-XX:+HeapDumpOnOutOfMemoryError:应用程序OOM时,默认在当前工作目录产生
java_pidxxx.hprof
的堆转储文件 -
若需指定dump文件的路径和文件名,可以使用
-XX:HeapDumpPath=/path/to/java_heapdump
进行设置 -
在实际应用过程中,只是产生dump文件,并不能满足需求,可能还需要再程序OOM时,及时发出告警信息以通知运维人员。这时,可以使用
-XX:OnOutOfMemoryError=self-definded-command
,执行自定义的shell脚本以实现OOM告警 -
在程序OOM时,如果想快速退出程序,可以选择
-XX:+CrashOnOutOfMemoryError
或-XX:+ExitOnOutOfMemoryError
,二者的区别可以参考《java命令中的options》的3.4节《Advanced Serviceability Options》
2. 线上服务关闭dump配置
-
在之前的工作中,为了分析OOM的原因并向运维人员发送告警,jvm的配置如下
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/opt/bidata_dump/ -XX:OnOutOfMemoryError=/opt/bigdata/bin/oom_process.sh -XX:+ExitOnOutOfMemoryError
-
后来,在服务运行的过程中发现,堆内存200GB+的线上服务,产生的dump文件差不多也是200GB+,而且产生dump文件大约需要20min,在这期间服务处于僵死状态
-
由于人力原因,目前不会基于dump文件进行OOM原因分析,我们更期望服务在OOM后能快速退出,借助我们的服务探活作业,快速重启服务
-
因此,将OOM配置修改如下,只保留
-XX:+ExitOnOutOfMemoryError
配置-XX:+ExitOnOutOfMemoryError
-
OOM时,
-XX:+ExitOnOutOfMemoryError
会在标准输出中打印如如下的信息(just an example),这些信息会重定向run.log中Terminating due to java.lang.OutOfMemoryError: Java heap space
-
基于这一事实,在服务探活作业中增加如下逻辑:
- 若发现服务已退出,则尝试获取run.log的内容,分析服务是否因为OOM而退出
- 然后在服务重启告警中,加上服务失败的原因(OOM 或 unknown reason)
3. 后记
- 如何开启dump配置,并执行shell脚本:JVM实战(一): dump文件的产生以及执行shell脚本
- 如需仔细了解OOM有关的JVM参数,可以参考《java命令中的options》,或者直接阅读oracle官方文档:Advanced Serviceability Options
- 相关参考资料: