当Java程序发生OOM(OutOfMemoryError)时,如果想要自动转储堆内存以便分析,可以在启动JVM时配置下列参数:
-XX:+HeapDumpOnOutOfMemoryError
这个参数可以让JVM在抛出OOM异常时自动生成heap dump文件。
-XX:HeapDumpPath=./java_pid<pid>.hprof
指定生成的heap dump文件的存放路径和文件名,这里使用了pid作为文件名的一部分,可以将不同时间的堆转储区分开。
-XX:OnOutOfMemoryError=<命令>
当OOM发生时,可以执行指定的命令,例如用于通知或执行脚本。
所以典型的带有堆转储的启动参数可以是:
java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./java_pid<pid>.hprof -Xmx512m ...
这样就可以在OOM发生时自动获取堆转储文件。分析这个文件可以定位内存泄漏或其他内存问题。
hprof文件自定义
一开始我想要使用生成时间作为heap dump文件名的一部分,配置方法如下:
-XX:HeapDumpPath=./java_oom-%t.hprof
经过实验,果然不行,原因是 HeapDumpPath 中如果使用 %t 或者 %%t 作为时间戳占位符,在运行时实际上并不能被 JVM 解析替换。
经过询问claude,得到两个解决方案,但是我还没实验,等验证过再来更新,先记录上
1.使用时间戳+计数器的方式生成唯一堆转储文件名
主要思路是:
-
启动Java程序时,使用一个循环脚本wrap着它