堆内存溢出案例分析( OutOfMemoryError )

  • 源代码
      public class TestClass1 {
          public static void main (String[] args) {
              ArrayList<TestClass1> list = new ArrayList<>();
              while ( true ) {
                  list.add( new TestClass1() );
              }
          }
      }
    
  • 分析

      由代码可得, 通过一个死循环我们不停的往list中添加TestClass1类对象, 从而使得堆中的对象个数不停的
      增加, 从而会造成堆内存溢出错误, 如下图:
    

  • JVM参数进一步测试堆内存溢出错误

      为了能够更快的造成堆内存溢出, 并且将堆内存的溢出错误发生的现场环境保存下来, 我们可以添加三个JVM
      参数[ -Xms5m -Xmx5m -XX:+HeapDumpOnOutOfMemoryError ], 参数的含义是设置虚拟机堆内存的最小值
      为5M, 最大值为5M, 即不存在堆内存的变化, 固定为5M, 如下图所示:
    

  • jvisualvm分析堆内存溢出错误输出的文件

      通过添加一个[ -XX:+HeapDumpOnOutOfMemoryError ]参数, 在发生该错误的时候会将堆当时的信息输出为
      一个后缀名为.hprof的文件, 执行jvisualvm命令打开GUI, 然后选择文件, 选中打开以.hprof后缀名的文件,
      下面我们对该文件进行简要的分析
    

jvisualvm分析类TestClass1运行时的状态

  • 修改源代码

      public class TestClass1 {
          public static void main (String[] args) {
              ArrayList<TestClass1> list = new ArrayList<>();
              while ( true ) {
                  list.add( new TestClass1() );
                  System.gc();
              }
          }
      }
    
      在上一个案例的基础上增加了一个System.gc()来主动让虚拟机执行垃圾回收, 我们发现增加了该代码后没有
      再出现堆内存溢出的错误, 程序处于一直运行状态, 此时我们通过jvisualvm来对该Java进程进行分析
    
  • 分析

results matching ""

    No results matching ""