从LeakCanary看内存快照生成

news2025/1/20 7:16:30

前面我们已经完成了生命周期监控并且可以通过ReferenceQueue和WeakHashMap的比较确定哪些对象发生泄漏了,那么接下来需要考虑的就是如何确定这个对象是被谁持有导致泄漏的呢?

从内存泄漏一文中可知,当我们使用Android Studio或MAT分析内存泄漏问题时,通常首先是需要抓取发生内存泄漏时的hprof文件,随后使用分析软件打开该文件,排查泄漏对象被持有的GC Roots,进而解决内存泄漏问题。

同样的,在上述场景中,我们确定了发生内存泄漏的对象,那么接下来自然也是抓取此时的hprof文件,随后使用某些工具库解析该文件,进而查找发生内存泄漏对象的持有关系,找到GC Roots即可。

hprof文件

文件后缀hprof是英文Heap Profile(内存快照)的缩写,该文件是由Java虚拟机(JVM)生成的一种二进制文件,用于记录Java程序运行时内存的使用情况、对象实例分布、方法调用情况、线程统计信息等。

hprof文件通常用于分析Java程序的性能问题,查找内存泄露、对象实例分布情况、方法调用次数等,从而提高程序的性能和稳定性。

hprof文件组成

相对于Java程序生成的hprof文件而言,Android程序生成的hprof文件新增了部分TAG,Android上的hprof文件由文件头和数据区组成,其中文件头占32位,主要包含格式名和版本号,标识符大小,高位时间戳等信息,数据区由若干个Record数据组成,每个Record数据中包含Tag,数据长度,数据内容等信息,如下图所示(更多hprof文件格式可以参考:hprof文件说明):

hprof structor

生成hprof文件

在常用开发工具中都可以生成hprof文件,如Android Studio Profiler,DDMS,eclipse,命令行工具等。通过ADB生成hprof文件的命令如下所示:

adb shell am dumpheap pid/pkgName fileName.hprof

以包名com.poseidon.wanandroid为例,导出该应用当前内存快照的操作如下图所示:

image-20230817220756084

image-20230817220925949

当然也可以通过代码来生成hprof文件,在android.os.Debug类的dumpHprofData方法即可生成hprof文件,函数声明如下:

image-20230813222719042

这两个函数的区别在于:只包含fileName参数的函数是将hprof数据写入fileName对应的文件中,而后者是写入fd参数中,后者主要用于支撑前面提到的shell命令。

接前文,我们已经知道了某个对象的销毁时机,并且知道可以通过ReferenceQueue检查其是否回收,那么检查回收的机制就可以设计成在对象销毁时触发延时任务去比对ReferenceQueue和WeakHashMap,如果比对后对象的key仍在HashMap中,则发生了内存泄漏,调用Debug.dumpHprofData方法生成hprof文件。

修改ObjectWatcher代码如下所示:

public void watch(Object object) {
    removeWeaklyReachableObjects();
    String key = UUID.randomUUID().toString();
    Log.d(TAG, "watch object:" + object + ",key:" + key);
    KeyedWeakReference weakReference = new KeyedWeakReference(key, object, mReferenceQueue);
    mReferences.put(key, weakReference);

    Handler mainHandler = new Handler(Looper.getMainLooper());
    mainHandler.postDelayed(new Runnable() {
        @Override
        public void run() {
            removeWeaklyReachableObjects();
            KeyedWeakReference keyedWeakReference = mReferences.get(key);
            if (keyedWeakReference != null) {
                // key对应的object可能发生内存泄漏,dump内存堆栈
                Log.d(TAG, "keyedReference:" + keyedWeakReference.toString());
                try {
                    Debug.dumpHprofData("/sdcard/Download/tmp.hprof");
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }

        }
    }, 5000);
}

private void removeWeaklyReachableObjects() {
    KeyedWeakReference keyedWeakReference = null;
    do {
        keyedWeakReference = (KeyedWeakReference) mReferenceQueue.poll();
        Log.d(TAG, "keyedWeakReference:" + keyedWeakReference);
        if (keyedWeakReference != null) {
            mReferences.remove(keyedWeakReference.getKey());
            Log.d(TAG, "object has been destroyed:" + keyedWeakReference.toString());
        }
    } while (keyedWeakReference != null);
}

在MainActivity制造经典的Handler内存泄漏场景,可以看到MainActivity泄漏确实被监控到了,如下图所示:

image-20230819111121031

同时在sdcard/Download目录中也生成了prof文件,如下所示:

image-20230819105142503

使用AS打开,可以看到MainActivity的GC Roots持有路径,根据持有路径就可以分析泄漏问题并处理。

image-20230819110335652

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/925636.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

vue3范围选择组件封装

个人项目地址: SubTopH前端开发个人站 (自己开发的前端功能和UI组件,一些有趣的小功能,感兴趣的伙伴可以访问,欢迎提出更好的想法,私信沟通,网站属于静态页面) SubTopH前端开发个人站…

测试框架pytest教程(10)自定义命令行-pytest_addoption

pytest_addoption pytest_addoption是pytest插件系统中的一个钩子函数,用于向pytest添加自定义命令行选项。 在pytest中,可以使用命令行选项来控制测试的行为和配置。pytest_addoption钩子函数允许您在运行pytest时添加自定义的命令行选项,…

四信智能充电桩解决方案

新能源汽车是信息技术与制造体系的全面融合,是产业发展的大势所趋,也是新动能的重要支点,而推进充电基础设施建设则是实现我国从汽车大国迈向汽车强国必由之路战略举措的有力保障。 据国际能源署测算,2030年全球私人充电桩保有量预…

数组和指针的练习解析(4)

题目: int main() { int aa[2][5] { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 }; int *ptr1 (int *)(&aa 1); int *ptr2 (int *)(*(aa 1)); printf( "%d,%d", *(ptr1 - 1), *(ptr2 - 1)); return 0; } 思路分析: int *ptr1 (int *)(&…

Java的锁大全

Java的锁 各种锁的类型 乐观锁 VS 悲观锁 乐观锁与悲观锁是一种广义上的概念,体现了看待线程同步的不同角度。在Java和数据库中都有此概念对应的实际应用。 先说概念。对于同一个数据的并发操作,悲观锁认为自己在使用数据的时候一定有别的线程来修改数…

AMBA总线协议(0)——目录与传送门

一、AMBA总线协议 Arm高级微控制器总线架构(Advanced Microcontroller Bus Architecture,AMBA)是一种开放式标准片上互联规范,用于连接和管理片上系统(System on Chip,Soc)中的功能块。 AMBA是一种广泛用于…

跨域知识点+springboot解决跨域

目录 一 跨域简介 二 跨域的三种情况 三 springboot解决跨域案例 一 跨域简介 什么是跨域? 由于浏览器的一些安全性限制,不允许前端页面访问一些协议不同、域名不同、端口号不同的http接口,例如我本地创建一个html,里面写一个a…

什么是代码审计?怎么做?

代码审计是对源代码进行人工或自动化审查,以查找潜在的安全漏洞和隐患。在信息安全测试中,代码审计是非常重要的一环。它主要包括以下几个方面: 1.变量验证:检查代码是否对变量进行验证,防止变量被恶意用户篡改。 2.…

python systemrdl 使用实例

今天来看一个具体实例,上一篇传送门:python SystemRDL 包介绍_Bug_Killer_Master的博客-CSDN博客 通常来说,我们验证过程用到的情况大多都是需要提取reg field的路径以及reset 值等信息,所以比较常见的一种方法就是先把rdl compil…

深入理解python虚拟机:调试器实现原理与源码分析

调试器是一个编程语言非常重要的部分,调试器是一种用于诊断和修复代码错误(或称为 bug)的工具,它允许开发者在程序执行时逐步查看和分析代码的状态和行为,它可以帮助开发者诊断和修复代码错误,理解程序的行…

vue(element ui安装)

目录 一,element ui安装二,main.js三,使用element ui最后 一,element ui安装 先在盘服中找到你创建的node的位置 如有不懂根据可以看看上一章安装node 然后在终端找到 进入这个位置之后就可以安装了 输入npm i element-ui -S这个…

什么是长短时记忆网络(LSTM)

什么是长短时记忆网络(LSTM) RNN有一定的记忆能力,但不幸的是它只能保留短期记忆,在各类任务上表现并不好,那该怎么办? 人们将目光投向了自己,人类的记忆是有取舍的,我们不会记住每时每刻发生的所有事,会…

基于Java+SpringBoot+vue前后端分离高校办公室行政事务管理系统设计实现

博主介绍:✌全网粉丝30W,csdn特邀作者、博客专家、CSDN新星计划导师、Java领域优质创作者,博客之星、掘金/华为云/阿里云/InfoQ等平台优质作者、专注于Java技术领域和毕业项目实战✌ 🍅文末获取源码联系🍅 👇🏻 精彩专…

奎文区残疾人联合会党组领导侯效刚、刘金玲莅临考察交流

2023年8月15日上午,为进一步提升残疾人精准化服务水平,推动“如康家园”残疾人之家建设有序展开,奎文区残疾人联合会党组书记兼理事长侯效刚,党组成员兼副理事长刘金玲,潍州路街道办事处副主任董江芹主任一行5人莅临潍…

RK3568评估板外接屏幕修改竖屏为横屏显示

问题 使用RK3568评估板外接HDMI屏幕时竖屏显示内容,需要修改为横屏显示。 解决办法 修改weston.ini配置文件,配置output输出参数 查看显示屏名称 使用ls /sys/class/drm/ 命令查看显示屏名称,如下图所示,示例屏为HDMI屏&#xff0…

1448. 统计二叉树中好节点的数目

题目描述: 给你一棵根为 root 的二叉树,请你返回二叉树中好节点的数目。 「好节点」X 定义为:从根到该节点 X 所经过的节点中,没有任何节点的值大于 X 的值。 示例: 解题思路: 通过左右子树分别判断是否大于…

胜券汇:运营商有望引领国内AI信创加速

8月20日,中国电信发布《中国电信AI算力服务器(2023-2024年)会集收购项目会集资历预审公告》。胜券汇研报点评称,中国电信集采4175台AI算力服务器,数量大幅增加,佐证AI服务器高景气量。估计国产占比约47%&am…

【三维重建】【深度学习】NeRF代码Pytorch实现--数据加载(上)

【三维重建】【深度学习】NeRF代码Pytorch实现–数据加载(上) 论文提出了一种5D的神经辐射场来作为复杂场景的隐式表示,称为NeRF,其输⼊稀疏的多⻆度带pose的图像训练得到⼀个神经辐射场模型。简单来说就是通过输入同一场景不同视角下的二维图片和相机位…

抢鲜体验!vLive虚拟直播5大实用新功能上线!

vLive虚拟直播系统2.6.2版本全新上线!新版本一共更新了5项实用功能,能让你的直播操作更加方便。现在就跟随小编一起来看看吧! 1.本地下载场景支持一键迁移 用户下载后的场景可以直接迁移至另一个磁盘,无需重复下载。 2.信号源添加…

《深度学习计算机视觉 》书籍分享(包邮送书三本)

深度学习计算机视觉介绍 随着计算机技术的发展和进步,计算机视觉领域得到了广泛的关注和研究。而深度学习作为一种强大的机器学习方法,已经成为计算机视觉领域的重要工具之一。本文将介绍深度学习在计算机视觉中的应用和取得的成果。 深度学习是一种模…