MAT

@bingoogolapple 2017-07-12 09:10:25发表于 bingoogolapple/bingoogolapple.github.io Java工具软件

安装

  • 独立安装
  • 以 Eclipse 插件的方式安装
    • Help -> Eclipse MarketPlace -> 搜索「Memory Analyzer」
    • Window -> Perspective -> Open Perspective -> Other -> Memory Analysis

生产 dump 文件

  • jmap -dump:format=b,file=heapDump 19898
  • Android
    • DDMS - AndroidSDK/platform-tools/hprof-conv xxx.xxx.xxx.hprof xxx.xxx.xxx.hprof
    • Android Studio - Export to standard.hprof

概念

  • 内存泄漏:对象无用了,但仍然可达(未释放),垃圾回收器无法回收
  • Shallow Heap:就是对象本身占用内存的大小,不包含对其他对象的引用
    • 常规对象(非数组)的 Shallow Heap 由其成员变量的数量和类型决定
    • 数组的 Shallow Heap 由数组元素的类型(对象类型、基本类型)和数组长度决定
  • Retained Heap:是该对象自己的 Shallow Heap,加上从该对象能直接或间接访问到对象的 Shallow Heap 之和。换句话说,Retained Heap 就是该对象被 GC 之后所能回收到内存的总和(当 A 和 B 同时引用 C 时,A 的 Retained Heap 是不准确的,需要排除被 GC Roots 直接或者间接引用的对象)
  • outgoing references:表示该对象的出节点(被该对象引用的对象)
  • incoming references:表示该对象的入节点(引用到该对象的对象)
  • GC Roots:GC 发现通过任何引用链无法访问某个对象的时候,该对象即被回收。名词 GC Roots 正是分析这一过程的起点,例如 JVM 自己确保了对象的可到达性(那么 JVM 就是 GC Roots),所以 GC Roots 就是这样在内存中保持对象可到达性的,一旦不可到达,即被回收。通常 GC Roots 是一个在当前线程的调用栈上的对象(例如方法参数和局部变量),或者是线程自身或者是系统类加载器加载的类以及 Native Code 保留的活动对象。所以 GC Roots 是分析对象为何还存活于内存中的利器
  • Java 的引用规则
    • Strong Ref (强引用):通常我们编写的代码都是 Strong Ref,于此对应的是强可达性,只有去掉强可达,对象才被回收
    • Soft Ref (软引用):如果一个对象只具有软引用,则内存空间足够,垃圾回收器就不会回收它;如果内存空间不足了,就会回收这些对象的内存。软引用可用来实现内存敏感的高速缓存,通过 java.lang.ref.SoftReference 类实现
    • Weak Ref (弱引用):只具有弱引用的对象拥有更短暂的生命周期。在垃圾回收器线程扫描它所管辖的内存区域的过程中,一旦发现了只具有弱引用的对象,不管当前内存空间足够与否,都会回收它的内存,不必等到内存吃紧的时候。通过 java.lang.ref.WeakReference 和 java.util.WeakHashMap 类实现
    • Phantom Ref (虚引用):根本不会在内存中保持任何对象,你只能使用 Phantom Ref 本身。一般用于在进入 finalize() 方法后进行特殊的清理过程,通过 java.lang.ref.PhantomReference 实现。虚引用必须和引用队列 (ReferenceQueue)联合使用。当垃圾回收器准备回收一个对象时,如果发现它还有虚引用,就会在回收对象的内存之前,把这个虚引用加入到与之关联的引用队列中