登录 |  注册
首页 >  架构·案例 >  架构师学习之路-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

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

上一篇: 内存泄漏情况和示例 ( 出现FullGC内存泄漏问题排查和分析)
下一篇: Java 架构师读哪些书好
推荐文章
  • 一.概述我们在考虑MySQL数据库的高可用的架构时,主要要考虑如下几方面:如果数据库发生了宕机或者意外中断等故障,能尽快恢复数据库的可用性,尽可能的减少停机时间,保证业务不会因为数据库的故障而中断。用作备份、只读副本等功能的非主节点的数据应该和主节点的数据实时或者最终保持一致。当业务发生数据库切换时
  • 一步一步推导出Mysql索引的底层数据结构。  Mysql作为互联网中非常热门的数据库,其底层的存储引擎和数据检索引擎的设计非常重要,尤其是Mysql数据的存储形式以及索引的设计,决定了Mysql整体的数据检索性能。我们知道,索引的作用是做数据的快速检索,而快速检索的实现的本质是数据结构。通过不同数
  • 如何看到老年代、新生代的对象有哪些呢?MAT是分析dump的神器(顺便吐槽:当然也是吃内存卡机器的怪兽)。通常我们会在出现fullGC时dump下堆内存,然后分析FullGC的原因。那如何获知整个堆内存里,有哪些对象在新生代、哪些在老年代呢?一个典型的应用场景是:出现了耗时超预期的YoungGC,我
  • 面向服务的架构(SOA)是一种软件开发方法,它使用称为服务的软件组件来创建业务应用程序。每项服务提供一种业务能力,并且服务也可以跨平台和语言相互通信。开发人员使用SOA来重用不同系统中的服务,或者组合几个独立的服务来执行复杂的任务。例如,一个组织中的多个业务流程需要用户身份验证功能。您可以创建一项身
  • 1.背景1.1什么是交互式推荐?交互式推荐是一种互动式实时推荐产品模块,主要通过理解用户需求、以互动的方式进行推荐。交互式推荐由Youtube在2018年提出,主要用于解决推荐系统的延迟和与用户互动偏弱的问题。从2021年下半年开始,美团外卖推荐技术团队在外卖首页Feed上持续进行探索,2022上半
  • 导读:老是出现堆内存不足,大量FullGC深知出现内存溢出应该怎么办,怎样通过排查找到源头分析来解决问题?正文:我们有个新服务上线运行一段时间后,老是出现堆内存不足,大量出现FullGC,有些实例甚至出现内存溢出错误:java.lang.OutOfMemoryError:Javaheapspace但
学习大纲