原创:转载需注明原创地址 https://www.cnblogs.com/fanerwei222/p/11904422.html
Java内存分析简单介绍:
1. # 设置内存溢出时自动生成堆内存快照信息 -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=D:\log\gc.hprof -XX:+PrintGCDetails -Xloggc:D:\log\gc.log 2. 使用Jmap(Java Memory Map) 生成 堆内存信息文件 HeapDump, 打印指定Java进程(或核心文件、远程调试服务器)的共享对象内存映射或堆内存细节 常见内存错误: outOfMemoryError 年老代内存不足。 outOfMemoryError:PermGen Space 永久代内存不足。 outOfMemoryError:GC overhead limit exceed 垃圾回收时间占用系统运行时间的98%或以上。 jmap -dump:live,format=b,file=d:/log/heapdump.hprof 1000 可以将1000进程的内存heap输出出来到d:\log\heapdump文件里; 用 MAT 分析: Histogram可以列出内存中的对象,对象的个数以及大小。 Dominator Tree可以列出那个线程,以及线程下面的那些对象占用的空间。 Top consumers通过图形列出最大的object。 Leak Suspects通过MA自动分析泄漏的原因。 Histogram: Class Name : 类名称,java类名 Objects : 类的对象的数量,这个对象被创建了多少个 Shallow Heap :一个对象内存的消耗大小,不包含对其他对象的引用 Retained Heap :是shallow Heap的总和,也就是该对象被GC之后所能回收到内存的总和 Shallow Size 对象自身占用的内存大小,不包括它引用的对象。 针对非数组类型的对象,它的大小就是对象与它所有的成员变量大小的总和。当然这里面还会包括一些java语言特性的数据存储单元。 针对数组类型的对象,它的大小是数组元素对象的大小总和。 Retained Size Retained Size=当前对象大小+当前对象可直接或间接引用到的对象的大小总和。(间接引用的含义:A->B->C, C就是间接引用) 换句话说,Retained Size就是当前对象被GC后,从Heap上总共能释放掉的内存。 不过,释放的时候还要排除被GC Roots直接或间接引用的对象。他们暂时不会被被当做Garbage GC ROOTS | |--ObjectA |--ObjectB |----|--ObjectC |----|--ObjectD |--ObjectD 可以看出, GC ROOTS直接引用了 A, B, D 三个对象: A : Retained Size(A) = Shallow Size(A) B : Retained Size(B) = Shallow Size(B) + Shallow Size(C) (此处因为D直接被GCROOTS引用, 所以这里不包含D) D : Retained Size(D) = Shallow Size(D) 如果D不被GC ROOTS直接引用如下: GC ROOTS | |--ObjectA |--ObjectB |----|--ObjectC |----|--ObjectD A : Retained Size(A) = Shallow Size(A) B : Retained Size(B) = Shallow Size(B) + Shallow Size(C) + Shallow Size(D) D : Retained Size(D) = Shallow Size(D)