目录
预备知识点1:Shallow Size Retained Size Heap Size Allocated
with outgoing references & with incoming references
一 查找java进程id
两种方法:
jps是jdk自带的命令,作用是显示系统内所有虚拟机进程(因为每一个java程序都会独占一个java虚拟机实例,所以也就是显示所有java进程)
ps -aux是linux自带的进程命令
jps -v
ps -aux | grep java
二 生成堆转储快照
jmap -dump:live,format=b,file=/tmp/***.dump pid
其中live是只dump出存活对象
ps:配置参数oom可自动生成heap dump文件
One can get a HPROF binary heap dump on an OutOfMemoryError for Sun JVM (1.4.2_12 or higher and 1.5.0_07 or higher), Oracle JVMs, OpenJDK JVMs, HP-UX JVM (1.4.2_11 or higher) and SAP JVM (since 1.5.0) by setting the following JVM parameter
-XX:+HeapDumpOnOutOfMemoryError
三 分析内存
工具
常用的工具有:VisualVM JProfiler MAT
推荐使用MAT(Eclipse Memory Analyzer tool)下载链接 http://www.eclipse.org/mat/downloads.php
MAT(Memory Analyzer Tool),一个基于Eclipse的内存分析工具,是一个快速、功能丰富的JAVA heap离线分析工具,它可以帮助我们查找内存泄漏和减少内存消耗。使用内存分析工具从众多的对象中进行分析,快速的计算出在内存中对象的占用大小,看看是谁阻止了垃圾收集器的回收工作,并可以通过报表直观的查看到可能造成这种结果的对象。
工作原理是对jvm堆内存的快照录制建立多种索引,并通过一些辅助工具及可视化视图展现指定维度的统计结果,进而辅助Developer了解JVM内存的对象级状态。
ps:官网下载mac安装报错
MAC安装MAT会提示错误解决方法
笔者双击提示错误,大致意思是错误日志写在某个目录下,打开日志文件,我们可以看到相关错误,大意是没有写入权限,并且可以使用-data参数指定不同的区域。
修改/mat.app/Contents/Eclipse/MemoryAnalyzer.ini文件
注意:1)data和路径必须在两个不同的行;2)data参数必须放在Laucher之前,否则启动还是不成功
使用MAT分析过大dump堆会报错,需要修改配置文件中的Xmx大小
使用场景
主要是对内存泄漏、内存溢出、内存占用高的精细化分析:
(1) 高峰期系统OutOfMemory,需要定位Error灾难的原因。
(2) 系统频繁FULL GC,需要定位影响服务实时性及稳定性的原因。
(3) 系统GC频率过高,需要定位吞吐量低浪费资源的原因。
(4) 系统运行一定时间总是OOM,需要重启解决
解决问题
(1) 捕获对象自身的详情信息,对dump文件提供分析及可视化支持。
(2) 对所有对象进行关联分析,定位JVM堆中占用内存较高的类及实例,并提供详细占比量。
(3) 提供任一对象的直接引用及间接引用详情(主要是内容及内存占用),进而提供完善的链路详情。
(4) 提供任一对象到GC Root的链路详情。
(5) 提供类加载的详细信息。
(6) 提供heap dump时刻线程概要信息及线程栈详细信息
(7) 提供一种类似于SQL的对象(类)级别统一结构化查询语言。
注:heap dump是特定时间点java进程的内存快照,包含了快照被触发时java对象和类在heap中的情况,由于快照只是瞬间的记录,所以其中不包含一个对象在何时、在哪个方法中被分配这样的信息
使用
预备知识点1:Shallow Size Retained Size Heap Size Allocated
Shallow Size
对象本身占用的内存空间,不包含其引用的对象,但在JAVA中除基本类型外,一切均为对象,也就是说持有的一直为对象的引用,如String类型对象,它主要包含3个int成员(3*4B)、1个char[]成员(1*4B)以及一个对象头(8B),尽管char[]可能指向一大块字符,但String对象里只有一个引用所占4B的空间,因此String类型对象的Shallow Size就是12B+4B+8B = 24B。
Retained Size
对象本身的Shallow Size + 对象能直接或间接访问到的对象的Shallow Size,也就是说Retained Size就是该对象被gc之后所能回收内存的总和。
Heap Size
堆的大小,当资源增加,当前堆的空间不够时,系统会增加堆的大小,若超过上限(如64M,阈值视平台而定)则会被杀掉
Allocated
堆中已分配的大小
预备知识点2:支配树(Dominator tree)
对象之间dominator关系树。如果从GC Root到达Y的的所有path都经过X,那么我们称X dominates Y。
预备知识点3:Top Consumers
展现哪些类、哪些classloader、哪些包占用最高比例的内存。
预备知识点4:OQL
类似于SQL的mat专用统一查询语言,可以根据条件对heap中的数据进行筛选。
例如查找size=0并且未使用过的ArrayList
select * from java.util.ArrayList where size=0 and modCount=0
根据Leak Suspects快速查看泄露的可疑点
点开Detail,可以获取实例到GC ROOT的最短路径、完整的引用链路、dominator路径、类型等详细信息
Dominator tree
从MAT的dominator tree中可以看到占用内存最大的对象以及每个对象的dominator。
with outgoing references & with incoming references
这两个是对象引用关系的穿梭查看方式,给定一个对象,with outgoing references可以获取该实例所引用的对象列表,with incoming references可以获取引用该实例的对象列表,两个功能可递归使用。
线程详情
通过thread_overview列表可以进入到到线程详情页面,进而获取到线程栈信息及占用内存的信息。
集合详情分析
筛选指定的Object(Hash Map,ArrayList)并按照大小进行分组:
查看那些具有预分配内存能力的集合,比如HashMap,ArrayList。计算方式:”size / capacity”
检测每一个HashMap或者HashTable实例并按照碰撞率排序,碰撞率 = 碰撞的实体/Hash表中所有实体