先上一个代码demo,利用unsafe开辟1g内存空间,不释放。
import java.lang.reflect.Field;
import java.util.concurrent.CountDownLatch;
import sun.misc.Unsafe;
public class OutOfHeapOOM {
public static final Unsafe UNSAFE;
static {
try {
Field theUnsafe = Unsafe.class.getDeclaredField("theUnsafe");
theUnsafe.setAccessible(true);
UNSAFE = (Unsafe) theUnsafe.get(null);
} catch (Exception e) {
throw new RuntimeException(e);
}
}
public static void main(String[] args) {
CountDownLatch latch = new CountDownLatch(1);
Thread thread = new Thread(() -> {
UNSAFE.allocateMemory(1024 * 1024 * 1024);
try {
latch.await();
} catch (InterruptedException e) {
e.printStackTrace();
}
});
thread.setName("oom thread");
thread.start();
}
}
javac?OutOfHeapOOM.java生成字节码文件
排查步骤:
java -XX:NativeMemoryTracking=detail OutOfHeapOOM
jcmd pid VM.native_memory detail scale=MB > temp.tx
根据下面的pmap命令输出的地址找到pid
strace -f -e trace=mmap java -XX:NativeMemoryTracking=detail OutOfHeapOOM
打印进程内存映射地址
pmap pid
查看线程栈快照
jstack pid
|