• 堆内存溢出时,系统会抛出异常并退出:java.lang.OutOfMemoryError: Java heap space
  • GC 日志不用分析,因为堆内存溢出往往对应着大量的 GC 日志,频繁的 GC,所以分析起来很麻烦;
  • 直接基于 MAT 分析 内存快照即可;

(1) 演示代码

  1. public class Demo3 {
  2. public static void main(String[] args) {
  3. long counter = 0;
  4. List<Object> list = new ArrayList<>();
  5. while(true){
  6. list.add(new Object());
  7. System.out.println("当前创建了第"+(++counter)+"个对象");
  8. }
  9. }
  10. }

(2) JVM 参数

  1. -Xms1m
  2. -Xmx1m
  3. -XX:+PrintGCDetails
  4. -Xloggc:gc.log
  5. -XX:+HeapDumpOnOutOfMemoryError
  6. -XX:HeapDumpPath=./
  7. -XX:+UseParNewGC
  8. -XX:+UseConcMarkSweepGC

(3) 基于 MAT 分析堆内存

  • main 线程通过局部变量引用了 949,192 个字节的对象;
  • 内存都被一个实例对象占用了,就是 java.lang.Object[]。

image.png

  • 这里可以看到 Object[] 里面的每个元素,就是一堆的 java.lang.Object;

image.png

  • 这里可以看到线程执行什么方法的时候创建了一大堆的对象;

image.png