Java内存溢出——OutOfMemoryError体验——JProfiler安装

在实际的开发过程中,我们经常遇到java.lang.OutOfMemoryError异常,那么如何定位是程序的哪里出现这个异常的呢?本博文将体验OutOfMemoryError的定位

本博文体验的软件环境

JDK版本 IDE
Java 1.8.0.144_x64 IDEA 2019.1
  • 编写OutOfMemoryError的代码
    public class Test {
        public static void main(String[] args) {
            List<E> list = new ArrayList<>();
            // 不断的循环添加对象
            while (true) {
                list.add(new E());
            }
        }
    }
    
    class E {
    
    }
  • 我们打开IDEA中的VM Arguements参数的设置
    image

image

然后我们在上面 VM options中输入-XX:+HeadDumpOnOutOfMemoryError -Xms20m -Xmx20m,下面的Working directory是生成的堆内存快照的目录路径

上述参数的意义:

  1. -XX:+HeapDumpOnOutOfMemoryError

生成堆内存的快照

  1. -Xms20m

为jvm启动时分配的内存,比如-Xms20m,表示分配20M

  1. -Xmx20m

设置JVM最大可用内存为20M

-Xms和-Xmx设置一样的,避免每次垃圾回收完成后JVM重新分配内存

  • 运行该程序

我们很快就能发现,程序报java.lang.OutOfMemoryError: Java heap space异常,在对应的目录环境下,我们可以发现生成了 堆内存快照,每次运行都生成当前运行进程号pid对应的内存版本快照,可以根据进程号获取对应的内存版本快照

image

这是一个hprof类型的文件,我们打开也是乱码,那么我们怎么查看呢?

  • 安装JProfiler内存分析工具

image

安装结束之后,如下图

image

注意,这里安装的插件只是将JProfiler的入口集成到IDEA中,我们还需要下载JProfiler软件安装到需要本机的环境中

下载的地址:
JProfiler

安装完成之后,我们来修改下我们的程序

    public class Test {
        public static void main(String[] args) {
            List<E> list = new ArrayList<>();
            while (true) {
                try {
                    Thread.sleep(100);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
                list.add(new E());
            }
        }
    }
    
    class E {
        // 让对象有一定大小
        public byte[] bytes = new byte[10 * 1024];
    }

程序中的睡眠主要是为了让程序不会一下子结束,我们就可以点击上面的jProfiler按钮,进入界面观察具体的内存情况

  • 执行程序,点击JProfiler按钮(上面截图的按钮)进行如下的操作:

image

显示当前程序执行的内存、CPU和GC的情况

image

从图中我们其实已经看到程序已经发生了GC了

点击【Memory】查看内存使用情况

image

从图中我们可以看到我们设置的最大可用的内存情况,并且当前看到当前随着程序运行,当使用的内存不断增大,达到最大的可用内存时,程序就会OutOfMemoryError,我们也可以通过选择不同的【Memory Pool】来查看不同区域的内存情况

  • 我们也可以软件来查看hprof类型的文件

之前我们配置过VM Options的参数,输入的内存快照,如果我们想看看内存快照具体是显示什么内容,我们可以通过 【Memory Analyzer】这个软件来查看

Memory Analyzer

这个是本地运行来查看dump日志的软件

image

如果我们想要查看具体的程序执行情况,想要查看是哪些代码造成内存溢出的,我们可以进行如下操作

image

从上图中我们可以看到造成内存异常的主要是om.amos.tools.common.E对象的大量创建

综上就是我们跟踪正常执行的和内存快照查看的具体操作,以后我们在整理JVM分析时可以用来跟踪程序执行情况以及发生GC的主要原因

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章