解决内存泄漏问题,Profiler工具的使用介绍

什么是内存泄漏

内存泄漏(Memory Leak)是指程序中已动态分配的堆内存由于某种原因程序未释放或无法释放,造成系统内存的浪费,导致程序运行速度减慢甚至系统崩溃等严重后果。

以上是官方针对内存泄漏的说法。说的通俗一点,应该释放的内存没有被正常释放,就是内存泄漏。当我们程序出现内存泄漏后,轻则影响运行速度,重则内存溢出,造成程序崩溃。

内存溢出(Out Of Memory,简称OOM)是指应用系统中存在无法回收的内存或使用的内存过多,最终使得程序运行要用到的内存大于能提供的最大内存

所以,当我们程序出现疑似内存泄漏的时候,千万要引起重视。

如何识别内存泄漏

找出程序中有内存泄漏风险的代码,我们可以通过人工去review代码,找出内存泄漏并解决掉;也可以借助adb命令去观察相关状态;也可以借助AndroidStudio提供的Profiler工具来检测。

Activity 内存泄漏检测用法

主要用到Profiler模块:

image.png

页面泄漏案例:

创建两个Activity 一个为默认Activity A,一个demo的Activity B,A启动B,然后在按下返回退出B页面,B中代码如下:

class ProfilerMainActivity : AppCompatActivity() {companion object {//定义一个静态变量,引用Activity实例var refAct: ProfilerMainActivity? = null}private lateinit var student: Studentoverride fun onCreate(savedInstanceState: Bundle?) {super.onCreate(savedInstanceState)setContentView(R.layout.activity_profiler_main)//让静态变量一直持有当前实例refAct = thisstudent = Student()student.sayHello()}
}

接下来,我们先使用Profiler工具的Capture heap dump抓取一段内存堆数据:

A启动B后:

image.png

image.png
此时还是正常的情况

退出B

当我们退出B页面时重新抓取一段:

image.png
可以看出Activity的ondestroy生命周期已经执行完成,按道理页面已经被销毁,内存中不应该继续有该对象,而该对象正是被上面的静态变量引用导致GC一直不能释放该对象。

模拟解决该问题

在上面页面中finish操作:

class ProfilerMainActivity : AppCompatActivity() {//省略。。。。override fun finish() {super.finish()refAct = null}
}

再重复上面抓取步骤抓取一次内存数据:

image.png
可以看出,内存中仍然存在该对象,但是该对象已经没有谁引用他,那么 他将会在下一次GC回收垃圾时,被回收掉,这里我们直接强制GC执行垃圾回收,看看猜测是否正确:

image.png

抓取

可以发现,ProfilerMainActivity实例已经不再出现在内存当中。

使用Record Java/Kotlin allocations

主要记录一段时间中堆的对象个数、销毁时间

还是上面的代码 这次我们看Studen这个对象,执行操作A–》B–》A–》B,然后多次强制执行垃圾回收,抓取数据如下

看上图,Studen被创建两次,所以整个过程一共记录了两个对象,1和2,他们之间的区别是1中 Dealloc Time 不为空,没有Instance details 因为Student在第一次启动页面时创建,退出B页面后,被GC回收了 整个活跃时间为1s05ms,而2中Dealloc Time不为空 说明还没被回收,Instance details中记录了这个对象的堆栈信息,还在堆中活跃。全文讲解了在Android开发中经常遇到的内存泄漏问题,以及如何使用Profiler工具检测。更多有关Android性能优化相关的技术可以参考《Android性能优化解析》点击可以查看详细的性能优化板块。

总结

Profiler工具为了我们能方便查看内存泄漏的地方,专门提供了一个View app heap 分类来报告哪些页面泄漏,同时,我们还可以在里面查看非页面类有没有正常被释放,比如单例,当我们退出某个功能后,手动把单例置为空(”销毁“),我们只需在强制GC后抓取一段内存数据查看该对象是否仍在活跃即可。

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mongodb导出聚合查询的数据

❗️❗️❗️在正文之前先要讲一个坑,就是mongoexport这个命令工具不支持导出聚合查询的数据,比如通过某某字段来分组 我查了一天关于mongoexport怎么来导出聚合查询的结果集,最终还是gpt给了我答案 😭 既然mongoexport不支持&…

赛氪助力全国大学生数学竞赛山东赛区圆满举办

近日,全国大学生数学竞赛山东赛区比赛有序进行,赛氪已连续6年助力本项赛事蓬勃发展。在中国高等教育学会高校竞赛评估与管理体系研究专家工作组发布的《2022全国普通高校大学生竞赛分析报告》中,本赛事荣登观察目录。 全国大学生数学竞赛旨在…

Matlab导出高清图片方法

一、背景 使用matlab绘制图片后,需要将图片导出为.jpg或.eps格式以便后期使用。但通过文件–另存为.jpg时,并没有清晰度选择,导出的图片只有30几k,以至于图片很模糊。 二、Matlab导出高清图片方法 文件—导出设置 1、大小&…

智慧畜牧小程序开发流程

本文将详细介绍智慧畜牧小程序的开发流程,包括需求分析、设计、开发、测试和上线等环节。同时,将深入思考智慧畜牧小程序的发展趋势和未来挑战,为读者提供有深度的思考和逻辑性的分析。 一、需求分析 1.明确目标用户:首先…

【MATLAB源码-第73期】基于matlab的OFDM-IM索引调制系统不同子载波数目误码率对比,对比OFDM系统。

操作环境: MATLAB 2022a 1、算法描述 OFDM-IM索引调制技术是一种新型的无线通信技术,它将正交频分复用(OFDM)和索引调制(IM)相结合,以提高频谱效率和系统容量。OFDM-IM索引调制技术的基本思想…

Stable Diffusion:最先进的文本生成图像模型

稳定扩散 生成式 AI 技术正在迅速发展,现在可以简单地根据文本输入生成文本和图像。Stable Diffusion 是一种文本到图像模型,使您能够创建逼真的应用程序。 扩散模型通过学习去除添加到真实图像中的噪声进行训练。这种降噪过程会产生逼真的图像。这些模…

SpringCloudGateway--Sentinel限流、熔断降级

目录 一、概览 二、安装Sentinel 三、微服务整合sentinel 四、限流 1、流控模式 ①直接 ②关联 ③链路 2、流控效果 ①快速失败 ②Warm Up ③排队等待 五、熔断降级 1、慢调用比例 2、异常比例 3、异常数 一、概览 SpringCloudGateway是一个基于SpringBoot2.x的…

[工业自动化-12]:西门子S7-15xxx编程 - PLC从站 - ET200 SP系列详解

目录 一、概述 1.1 概述 二、系统组成 2.1 概述 2.2 与主站的通信接口模块 2.3 总线适配器 2.4 基座单元 2.5 电子模块 2.6 服务器模块 一、概述 1.1 概述 PLC ET200 SP 是西门子(Siemens)公司生产的一款模块化可编程逻辑控制器(PL…

Python教程之字典(Dictionary)操作详解

文章目录 前言一、创建字典二、访问字典里的值三、访问字典里的值四、删除字典元素五、字典键的特性六、字典内置函数&方法七、字典练习代码关于Python技术储备一、Python所有方向的学习路线二、Python基础学习视频三、精品Python学习书籍四、Python工具包项目源码合集①Py…

Spring Boot自动配置原理、实战、手撕自动装配源码

Spring Boot自动配置原理 相比较于传统的 Spring 应用,搭建一个 SpringBoot 应用,我们只需要引入一个注解 SpringBootApplication,就可以成功运行。 前面四个不用说,是定义一个注解所必须的,关键就在于后面三个注解&a…

Elasticsearch内存分析

文章目录 Elasticsearch JVM内存由哪些部分组成Indexing BufferNode Query CacheShard Request CacheField Data CacheSegments Cache查询 非堆内存内存压力mat分析es的jvm缓存监控 Elasticsearch JVM内存由哪些部分组成 官方建议Elasticsearch设置堆内存为32G,因为…

C# Dictionary与List的用法区别与联系

C#是一门广泛应用于软件开发的编程语言,其中Dictionary和List是两种常用的集合类型。它们在存储和操作数据时有着不同的特点和用途。本文将详细探讨C# Dictionary和List的用法区别与联系,并通过代码示例进行对比,以帮助读者更好地选择适合自己…