通过使用如下命令,查看所有的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》
在之前的工作中,为了分析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
基于这一事实,在服务探活作业中增加如下逻辑: