JVM内存泄漏排查一篇就懂

本文介绍了Java中的内存泄漏概念,OutOfMemoryError的原因,内存溢出与内存泄漏的区别,以及如何通过JVM启动参数和工具(如jps,jstat,jmap,MAT)进行内存泄漏排查。着重讲解了使用jmap和MAT进行堆转储分析的方法。
摘要由CSDN通过智能技术生成
JVM内存泄漏排查一篇就懂
什么是OutOfMemoryError
  • java.lang.OutOfMemoryError:是指程序在申请内存时,没有足够的内存空间供其使用,出现OutOfMemoryError。产生原因产生该错误的原因主要包括:
    • JVM内存过小。
    • 程序不严密,产生了过多的垃圾。
  • 一般情况下,在程序上的体现为:
    • 内存中加载的数据量过于庞大,如一次从数据库取出过多数据。
    • 集合类中有对对象的引用,使用完后未清空,使得JVM不能回收。
    • 代码中存在死循环或循环产生过多重复的对象实体。
    • 使用的第三方软件中的BUG。
    • 启动参数内存值设定的过小。
什么是内存泄漏

Memory Leak是指程序在申请内存后,无法释放已申请的内存空间,一次内存泄露危害可以忽略,但内存泄露堆积后果很严重,无论多少内存,迟早会被占光。在Java中,内存泄漏就是存在一些被分配的对象,这些对象有下面两个特点:

  • 首先,这些对象是可达的,即在有向图中,存在通路可以与其相连;
  • 其次,这些对象是无用的,即程序以后不会再使用这些对象。

如果对象满足这两个条件,这些对象就可以判定为Java中的内存泄漏,这些对象不会被GC所回收,然而它却占用内存。关于内存泄露的处理页就是提高程序的健壮型,因为内存泄露是纯代码层面的问题。

内存溢出和内存泄露的联系

内存泄露会最终会导致内存溢出。

相同点:都会导致应用程序运行出现问题,性能下降或挂起。

不同点:内存泄露是导致内存溢出的原因之一,内存泄露积累起来将导致内存溢出。内存泄露可以通过完善代码来避免,内存溢出可以通过调整配置来减少发生频率,但无法彻底避免。

JVM相关的启动参数
  • -XX:+HeapDumpOnOutOfMemoryErro

    从字面就可以很容易的理解,在发生OutOfMemoryError异常时,进行堆的Dump,这样就可以获取异常时的内存快照了。

  • -XX:HeapDumpPath=D:heap-dump

    这个也很好理解,就是配置HeapDump的路径,方便我们管理,这里我们配置为D:heap-dump,当然你也可以根据自己的需要,定义为其他的目录。

如何排查
确定频繁Full GC现象
【jps】虚拟机进程状况工具
  • 使用jps找出这个进程在本地虚拟机的唯一ID,因为在后面的排查过程中都是需要这个LVMID来确定要监控的是哪一个虚拟机进程。
  • 命令格式为:jps [ options ] [ hostid ]
    • 常用jps -l。
【jstat】虚拟机统计信息监视工具
  • 查看已使用空间站总空间的百分比.

  • 命令格式:jstat [ option vmid [interval[s|ms] [count]] ]

    • jstat -gcutil 20954 1000
      • gcutil指:已使用空间站总空间的百分比。
      • 20954指:pid
      • 1000指:每1000毫秒查询一次,一直查。

在这里插入图片描述

这台服务器的新生代Eden区(E,表示Eden)使用了28.30%(最后)的空间,两个Survivor区(S0、S1,表示Survivor0、Survivor1)分别是0和8.93%,老年代(O,表示Old)使用了87.33%。程序运行以来共发生Minor GC(YGC,表示Young GC)101次,总耗时1.961秒,发生Full GC(FGC,表示Full GC)7次,Full GC总耗时3.022秒,总的耗时(GCT,表示GC Time)为4.983秒。

找出导致频繁Full GC的原因

分析方法通常有两种:

  • 把堆dump下来再用MAT等工具进行分析,但dump堆要花较长的时间,并且文件巨大,再从服务器上拖回本地导入工具,这个过程有些折腾,不到万不得已最好别这么干。
  • 更轻量级的在线分析,使用“Java内存影像工具:jmap”生成堆转储快照(一般称为headdump或dump文件)。
【jmap】使用
  • jmap命令格式:jmap [ option ] vmid

  • 使用命令如下:jmap -histo:live 20954

在这里插入图片描述

可以看出HashTable中的元素有5000多万,占用内存大约1.5G的样子。这肯定不正常。

  • 如果上面一步还无法定位到关键信息,那么需要拿到heap dump,生成离线文件,做进一步分析,

  • 使用命令如:jmap -dump:live,format=b,file=heap.hprof 3514

在这里插入图片描述

MAT插件使用
  • 拿到heap dump文件,利用eclipse插件MAT来分析heap profile。

在这里插入图片描述

  • 直接看到下面Action窗口,有4种Action来分析heap profile,介绍其中最常用的2种:

    • Histogram:这个使用的最多,跟上面的jmap -histo 命令类似,只是在MAT里面可以用GUI来展示应用系统各个类产生的实例。

在这里插入图片描述

* Shllow Heap排序后发现 Cms_Organization 这个类占用的内存比较多(没有得到及时GC),查看引用:

在这里插入图片描述

* 分析引用栈,找到无效引用,打开源码:

在这里插入图片描述

  • Dominator Tree:这个使用的也比较多,显示大对象的占用率。

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值