Hprof基本概念

hprof最初是由J2SE支持的一种二进制堆转储格式,hprof文件保存了当前java堆上所有的内存使用信息,能够完整的反映虚拟机当前的内存状态。
格式

Hprof文件由FixedHead和一系列的Record组成,Record包含字符串信息、类信息、栈信息、GcRoot信息、对象信息。每个Record都是由1个字节的Tag、4个字节的Time、4个字节的Length和Body组成,Tag表示该Record的类型,Body部分为该Record的内容,长度为Length。

Android中的hprof

在Android设备上,我们可以通过两种方式生成当前进程的hprof文件

通过调用Debug.dumpHprofData(String filePath)方法来生成hprof文件
通过执行shell命令adb shell am dumpheap pid /data/local/tmp/x.hprof来生成指定进程的hprof文件到目标目录

然而Android平台上的hprof文件和标准Java的hprof定义有一些区别,主要是版本号不一样,而且增加了一些特殊Tag,在art/runtime/hprof/hprof.cc中有如下定义

可以看出Android增加了额外的9个HeapTag,其中比较重要的是HPROF_HEAP_DUMP_INFO。Android上将java堆分为Heap-App、Heap-Image、Heap-Zygote三块,这个Tag的作用是切换当前的堆,该Tag后面紧跟着一个4个字节的堆id和一个堆名称id。
比如出现一个HPROF_HEAP_DUMP_INFO Record,且该Record表示Heap-Image,那么表示后续所有Record中的类、对象、GCRoot对象均在Heap-Image中存储,直到下一个HPROF_HEAP_DUMP_INFO出现为止。

内存泄漏

内存泄漏指的是一个本该被回收的对象因为某些原因导致其不能被回收,通俗来说就是该对象理论上不再使用,但是仍无法被回收。

Android中的泄漏对象

判断一个对象是否泄漏首先要判断该对象是否不再使用,想要判断这一点则需要对象有明显的生命周期,在Android中有以下对象可以判断是否泄漏:

1、Activity: 通过Activity的mDestroyed属性来判断该Activity是否已经销毁,如果已经销毁且未被回收则认为是泄漏
Fragment: 通过Fragment的mFragmentManager是否为空来判断该Fragment是否处于无用状态,如果mFragmentManager为空且未被回收则认为是泄漏。

2、View: 通过unwrapper mContext获得Activity,如果存在Activity,则判断该Activity是否泄漏。

Editor: Editor指的是android.widget包下的Editor,是用于TextView处理editable text的辅助类,通过mTextView是否为空来判断Editor是否处于无用状态,如果mTextView为空且未被回收则认为是泄漏。

3、ContextWrapper: 通过unwrapper ContextWrapper获得Activity,如果存在Activity,则判断该Activity是否泄漏。

4、Dialog: 通过mDecor是否为空判断该Dialog是否处于无用状态,如果mDecor为空且未被回收则认为是泄漏。

5、MessageQueue: 通过mQuitting或者mQuiting(应该是历史原因,前期拼写错误为mQuiting,后来改正)来判断MessageQueue是否已经退出,如果已经退出且未被回收则认为是泄漏。

ViewRootImpl: 通过ViewRootImpl的mView是否为空来判断该ViewRootImpl是否处于无用状态,如果mView为空且未被回收则认为是泄漏。

6、Window: 通过mDestroyed来判断该Window是否处于无用状态,如果mDestroyed为true且未被回收则认为是泄漏。
Toast: 拿到mTN,通过mTN的mView是否为空来判断当前Toast是否已经hide,如果已经hide且未被回收则认为是泄漏。

泄漏的形式

泄漏的本质就是无用对象被持有导致无法回收,具体的形式有如下几种:

1、非静态内部类、匿名内部类持有外部类对象引用: 一般为用于回调的Listener,该Listener被别的地方持有,间接导致外部类对象被泄漏。
2、Handler: 在Activity中定义Handler对象的时候,Handler持有Activity同时Message持有Handler,而Message被MessageQueue持有,最终导致Activity泄漏。

3、资源对象未关闭: 数据库连接、Cursor、IO流等使用完后未close。

4、属性动画: 使用ValueAnimator和ObjectAnimator的时候,未及时关闭动画导致泄漏。Animator内部向AnimationHandler注册listener,AnimationHandler是一个单例,如果不及时cancel,会导致Animator泄漏,间接导致Activity/Fragment/View泄漏(比如Animator的updateListener一般都以匿名内部类实现)

5、逻辑问题: 注册监听器之后未及时解注册,比如使用EventBus的时候没有在合适的时候进行解注册

profiler使用

通过下载hprof文件,解压缩后,直接拖到Android studio中,可以通过Android studio中的profiler工具进行分析,如下图:
1、Heap Dump
1、筛选
左边区域可以通过筛选查看到泄漏的activity或者fragment,在Android中的泄漏主要是activity或者fragment有生命周期的类泄漏。
2、Heap区分
Heap 中主要分为三种:

1、app heap
当前APP从堆中分配的内存
2、image heap
系统启动映像,包含启动期间预加载的类。 此处的分配保证绝不会移动或消失
3、zygote heap
zygote是所有APP进程的母进程,linux 的进程使用COW技术,所有的APP共享zygote的内存空间,因此堆的话也继承了,并且zygote的这些空间不允许写入,为了加快java的启动和运行速度,zygote在启动时预加载了许多资源和代码,这样可以提高APP的运行速率.
源码

enum HprofHeapId {HPROF_HEAP_DEFAULT= 0,HPROF_HEAP_ZYGOTE= 'Z',HPROF_HEAP_APP= 'A',HPROF_HEAP_IMAGE= 'I',
};if (space->IsZygoteSpace()) {heap_type= HPROF_HEAP_ZYGOTE;VisitRoot(obj, RootInfo(kRootVMInternal));} else if (space->IsImageSpace() && heap->ObjectIsInBootImageSpace(obj)) {// Only countobjects in the boot image as HPROF_HEAP_IMAGE, this leaves app image objects as// HPROF_HEAP_APP.b/35762934heap_type= HPROF_HEAP_IMAGE;VisitRoot(obj, RootInfo(kRootVMInternal));}} else {const auto* los = heap->GetLargeObjectsSpace();if (los->Contains(obj) && los->IsZygoteLargeObject(Thread::Current(), obj)) {heap_type= HPROF_HEAP_ZYGOTE;VisitRoot(obj, RootInfo(kRootVMInternal));}

2、Instance View

点击heap dump中具体的类,右边就会展示instance view
Instance view中主要展示对象相关的信息

1、Depth
depth是从gc roots到选中的当前对象的引用链最短长度。在java垃圾回收机制中,被gc roots引用到的对象不会被回收。如下图:在gc root 引用树之外的对象会被回收。

Android中gc root 主要分为下面几类:

2、Native Size
native对象的内存大小,这个值只有在Android 7.0以及更高的版本可见。
3、Shallow Size
对象本身占用的内存,不包括它引用的其他实例

Shallow Size = [类定义] + 父类fields所占空间 + 自身fields所占空间 + [alignment]

4、Retained Size
Retained Size是指, 当实例A被回收时, 可以同时被回收的实例的Shallow Size之和,所以进行内存分析时,应该重点关注Retained Size较大的实例; 或者可以通过Retained Size判断出某A实例内部使用的实例是否被其他实例引用.
如下图:

上图中:obj1的retained size=obj1+obj2+obj4的shallow size,注意由于obj3被gc roots直接引用,所以这个值不计算到obj1的retained size中。

如上图:obj1的retained size=obj1+obj2+ obj3+obj4的shallow size

3、Reference

reference里面主要是类的引用关系,可以通过引用关系,一层一层的查看类是如何泄漏的。

参考

1、Android中内存泄漏相关
2、hprof文件相关
3、profile分析内存泄漏

android中hprof文件分析相关推荐

  1. Android Studio - HPROF文件查看和分析工具

    Android Studio - HPROF文件查看和分析工具 Android Studio 翻译的官方文章 原文链接 当你在Android Studio中使用Android Monitor里的Mem ...

  2. android studio .hprof,Android Studio - HPROF文件查看和分析工具

    转载自:http://www.cnblogs.com/xgjblog/p/6084388.html Android Studio 翻译的官方文章 原文链接 当你在Android Studio中使用An ...

  3. Android中AppWidget的分析与应用:AppWidgetProvider .

    from: http://blog.csdn.net/thl789/article/details/7887968 本文从开发AppWidgetProvider角度出发,看一个AppWidgetPrv ...

  4. 修改Android中的文件权限

    在Android中有一个精简版的linux系统,因为是linux系统,那么有时候在写Android应用程序的时候会遇到权限问题.我们都知道在shell中可以通过chmod命令来修改权限,所以就希望通过 ...

  5. android 生成aar文件,Android 中.aar文件生成方法与用法

    https://i.cnblogs.com/EditPosts.aspx?opt=1 无论是用Eclipse还是用Android Studio做android开发,都会接触到jar包,全称应该是:Ja ...

  6. Android中Assets文件路径

    Android中Assets文件绝对路径是不存在的 一般Assets文件夹里放些网页文件html.css.js 在网页文件中引用assets里的文件可以使用file:///android_asset/ ...

  7. Android中R文件ID值

    Android中R文件ID值 文章目录 Android中R文件ID值 前言 知识回顾 在代码中访问资源 语法 R文件 Lib库的R文件 AAR中的R文件 依赖库R文件的生成 R文件的数量 后续疑问 官 ...

  8. android 读写文件 简书,Android 中的文件操作

    Android 文件操作 概述 Android 中的文件操作主要涉及到两个部分,一个是内部存储的读写,一个是外部存储的读写两者的主要区别如下表: 内部存储 外部存储 始终可用 它并非始终可用,因为用户 ...

  9. Android中的文件读写操作

    在android开发中文件操作使用的其实还是比较高频的,之前我遇到这种需求都随便写写,对此没有一个比较全面的认识,所以想借这篇文章来梳理一遍. 由于需要读写文件,这包含了读写外部sd card的文件, ...

最新文章

  1. react antd Table 选中某一行,其它行也被选中了
  2. mysql做主从复制配置案例
  3. Sklearn 损失函数如何应用到_机器学习大牛最常用的5个回归损失函数,你知道几个?...
  4. 一个写得很不错的vuex详解(转)
  5. adobe blueprint
  6. 硬盘安装Win7教程!无光驱无U盘照样装Win7
  7. 云计算和虚拟化 - 虚拟化的介绍
  8. Git GitHub GitLab 超全面学习笔记 -- 匠心之作
  9. oracle dbms lob,Oracle中LOB 处理(dbms_lob的一些用法)
  10. 【NOIP2017提高A组冲刺11.2】救赎(数学期望)
  11. 洛谷 P3807 【模板】卢卡斯定理/Lucas 定理
  12. 获取和设置默认打印机
  13. YOLOv4原文翻译 - v4它终于来了!
  14. 记录ubuntu22.04突然连不上网
  15. 小明的成绩从去年的72分提升到了今年的85分,请计算小明成绩提升的百分点
  16. openCV中基于HSV的颜色判断(红色为例)
  17. MVG学习笔记(7) --自动标定和3D图形模型
  18. Dynamics CRM Server 2011出错,CRM Organization无法打开,无法创建和导入Organization的问题...
  19. 深度原创丨揭开工业互联网看不见的手:从MindSphere+Mendix谈起
  20. mac下iterm使用rz指令卡死解决方法

热门文章

  1. 那些你重复百度却始终记住不住的问题: N=NP?
  2. JS为什么是单线程?
  3. Android手机蓝牙连接热敏打印机 打印票据
  4. python基础——100多个Python挑战性编程练习
  5. mybatis oracle 使用mybatis-generator生成bean、mapper、dao
  6. jquery周历插件jqueryweekcalendar汉化实现【带节日】
  7. Android 新版引入aar包的方法
  8. 阿里巴巴字体图标库iconfont使用步骤
  9. java程序员的开发Python游戏自动化脚本(调用大漠插件)系列(一)起源
  10. 163邮箱存储空间使用情况在哪看