登录 |  注册
首页 >  架构·案例 >  架构师学习之路-Java开发实战学习笔记 >  MAT如何查看老年代对象-内存泄漏分析

MAT如何查看老年代对象-内存泄漏分析

如何看到老年代、新生代的对象有哪些呢?

MAT是分析dump的神器(顺便吐槽:当然也是吃内存卡机器的怪兽)。通常我们会在出现 fullGC 时 dump下堆内存,然后分析FullGC的原因。那如何获知整个堆内存里,有哪些对象在新生代、哪些在老年代呢?

一个典型的应用场景是:出现了耗时超预期的YoungGC,我们使用 【jstat -gcutil PID 1000】(每秒采一个点) 观察 Eden区的使用情况,在Eden 即将用满时 手动执行 【 jmap -dump:format=b,file=heap.hprof 】触发 Heap dump。然后分析到底是哪些对象 进入了新生代,导致YoungGC耗时这么长的。

1. 利用指令jmap dump文件

JDK自带了一些工具可以帮助我们查看JVM运行的堆内存情况,常用的是jmap命令

jmap.png

jmap -heap <pid>  打印堆的使用情况

jmap打印堆的使用情况.png

那么,从这个输出中我们也可以大致看出堆的结构,分为Young Generation (年轻代) 和 Old Generation (老年代)

Young Generation又被划分为:Eden Space , From Space 和 To Space

可以看到这里To区是干净的,还未被使用,From区已经使用了95%了

jmap -histo[:live] <pid>  打印类的实例数量、占用的内存、类的名称,通常我们并不需要看所有的,只需要看前几条即可

jmap打印堆的使用情况2.png

jmap -dump:live,format=b,file=heap.bin <pid>  

以hprof二进制格式dump堆的使用情况(PS:相当于生成一个快照,后续我们可以对这个快照文件进行分析)

jmapdump.png

2.Memory Analyzer (MAT)

文件dump下来以后,可以使用Eclipse的MAT插件进行查看

如果日常开发用的是eclipse的话,可以直接安装这个插件,如果不是的话,这个插件也可以独立运行

https://www.eclipse.org/mat/

https://www.eclipse.org/mat/downloads.php

解压之后双击MemoryAnalyzer.exe即可运行, 导入刚才dump的文件,效果如下图:

导入mat文件.png

点击Leak Suspects(泄露疑点) , 可以查看内存泄漏的大对象有哪些

leak suspects.png

还有其他使用可以参考相关教程

3. 查看老年代对象有哪些

需要先查看老年代地址范围,可以使用./vjmap.sh -address PID 打印得到heap地址区间,(或查看gc日志)比如:

Heap after GC invocations=1044 (full 0):
 par new generation   total 1677760K, used 8859K [0x00000006c0000000, 0x0000000740000000, 0x0000000740000000)
  eden space 1258368K,   0% used [0x00000006c0000000, 0x00000006c0000000, 0x000000070cce0000)
  from space 419392K,   2% used [0x000000070cce0000, 0x000000070d586c68, 0x0000000726670000)
  to   space 419392K,   0% used [0x0000000726670000, 0x0000000726670000, 0x0000000740000000)
 concurrent mark-sweep generation total 2097152K, used 328368K [0x0000000740000000, 0x00000007c0000000, 0x00000007c0000000)
 Metaspace       used 162911K, capacity 173128K, committed 173312K, reserved 1202176K
  class space    used 19543K, capacity 21388K, committed 21504K, reserved 1048576K
}

根据打印信息得到老年代区间:从0x0000000740000000开始,0x00000007c0000000结束

 concurrent mark-sweep generation total 2097152K, used 328368K [0x0000000740000000, 0x00000007c0000000, 0x00000007c0000000)

打开MAT OQL窗口,输入如下语句,然后点击红色感叹号执行,最终效果如下图,即可看到老年代对象列表:

SELECT * FROM INSTANCEOF java.lang.Object t WHERE (toHex(t.@objectAddress) >= "0x740000000" AND toHex(t.@objectAddress) <= "0x7c0000000")

oql.png

根据对象大小和分布,再结合代码即可分析出内存泄漏的原因。

原文链接: https://www.yukx.com/architect/article/details/2377.html 优科学习网MAT如何查看老年代对象-内存泄漏分析

<<上一课程
下一课程>>
推荐文章
  • 如何看到老年代、新生代的对象有哪些呢?MAT是分析dump的神器(顺便吐槽:当然也是吃内存卡机器的怪兽)。通常我们会在出现fullGC时dump下堆内存,然后分析FullGC的原因。那如何获知整个堆内存里,有哪些对象在新生代、哪些在老年代呢?一个典型的应用场景是:出现了耗时超预期的YoungGC,我
  • 面向服务的架构(SOA)是一种软件开发方法,它使用称为服务的软件组件来创建业务应用程序。每项服务提供一种业务能力,并且服务也可以跨平台和语言相互通信。开发人员使用SOA来重用不同系统中的服务,或者组合几个独立的服务来执行复杂的任务。例如,一个组织中的多个业务流程需要用户身份验证功能。您可以创建一项身
  • 1.背景1.1什么是交互式推荐?交互式推荐是一种互动式实时推荐产品模块,主要通过理解用户需求、以互动的方式进行推荐。交互式推荐由Youtube在2018年提出,主要用于解决推荐系统的延迟和与用户互动偏弱的问题。从2021年下半年开始,美团外卖推荐技术团队在外卖首页Feed上持续进行探索,2022上半
  • 导读:老是出现堆内存不足,大量FullGC深知出现内存溢出应该怎么办,怎样通过排查找到源头分析来解决问题?正文:我们有个新服务上线运行一段时间后,老是出现堆内存不足,大量出现FullGC,有些实例甚至出现内存溢出错误:java.lang.OutOfMemoryError:Javaheapspace但
  • 其实强引用、软引用、弱引用、虚引用这四个概念非常简单好记。在开头先总结一下这四个引用的特点吧。强引用:gc时不会回收软引用:只有在内存不够用时,gc才会回收弱引用:只要gc就会回收虚引用:是否回收都找不到引用的对象,仅用于管理直接内存接下来详细看看这四种引用,结合代码,深刻的体会一下。强引用即我们平
  • 在Linux中,CPU主要用于中断、内核以及用户进程的任务处理,优先级为中断内核用户进程,在学习如何分析CPU消耗状况前。先要掌握三个重要的概念1、上下文切换每个CPU在同一时间只能执行一个线程,Linux采用的是抢占式调度,即为每个线程分配一定的执行时间,当到达执行时间、线程中有IO阻塞或高级优先
学习大纲