JavaVM内でOutOfMemoryErrorが発生した場合は、当然オプションに従ってヒープダンプ(java_pid*.hprof)が出力される。 一方、Linux上で動作するJavaVMがOOM Killerでkillされた場合、同じオプションを指定していてもヒープダンプは出力されない。
以下のようなプログラムを作成し、
import java.util.Random; public class Test { public static void main(String [] args) { final int SIZE = 100000000; StringBuilder sb = new StringBuilder(); String r = "1234567890"; sb = new StringBuilder(SIZE); for (int i=0; i<SIZE/10; i++) { sb.append(r); } while(true){ } } }
Windows WSL2上のUbuntuで以下のコマンドを実行。Javaのバージョンは1.8.0_362。
javac Test.java; java -Xmx12000m -Xms12000m -XX:+HeapDumpOnOutOfMemoryError -XX:+CrashOnOutOfMemoryError -verbose:gc -Xloggc:./gc.log-%t -XX:+UseGCLogFileRotation -XX:+PrintGCDateStamps -XX:+PrintGCDetails -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=1m Test
しばらくするとOOM Killerが実行され、dmesg -T
の結果には以下が出力される。
[Sun Mar 12 03:30:54 2023] Out of memory: Kill process 6895 (java) score 979 or sacrifice child [Sun Mar 12 03:30:54 2023] Killed process 6895 (java) total-vm:15506224kB, anon-rss:7847124kB, file-rss:0kB, shmem-rss:0kB [Sun Mar 12 03:30:54 2023] oom_reaper: reaped process 6895 (java), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB
このとき、カレントディレクトリにはヒープダンプどころかエラーログ(hs_err_*.log)も出力されない。
satob@MACHINE:/mnt/c/path/to/dir$ ls Test.class Test.java