当前位置: 首页 > news >正文

性能优化中使用Profiler进行内存泄露的排查及解决方式

文章目录

  • 一、前言
  • 二、内存泄露的排查方式
  • 三、参考链接

一、前言

对于常规意义上的线程使用要及时关闭,数据库用完要及时关闭,数据用完要及时清空等等这里不再赘述,但是在开发中总会有不熟悉的api,开发进度过快,开发人员粗心等等原因导致内存泄露。可以使用leakcanary(参考链接:https://square.github.io/leakcanary/)内存检测处理,或者使用lint(参考链接:https://developer.android.google.cn/studio/write/lint?hl=zh-cn)静态代码检测后=,或者开启严格模式StrictMode(参考链接:https://developer.android.google.cn/reference/android/os/StrictMode),或者使用Profiler(参考链接:https://developer.android.com/studio/profile/android-profiler?hl=zh-cn)等等不同的方式进行内存泄露的检查。本文记录Profiler进行内存泄露检查的使用方式。

需要注意的是本篇文章采用了Android Studio新版的UI进行操作,具体开启方式为Preferences->Appearance & Behavior ->New UI 。然后勾选Enable new UI并重启Android Studio。开发工具版本为

Android Studio Giraffe | 2022.3.1 Patch 4
Build #AI-223.8836.35.2231.11090377, built on November 14, 2023
Runtime version: 17.0.6+0-17.0.6b829.9-10027231 aarch64
VM: OpenJDK 64-Bit Server VM by JetBrains s.r.o.

目前为最新版本开发工具。
测试工具为红米K60,版本为Android13
如需打开 Profiler 窗口,请依次选择 View > Tool Windows > Profiler,或点击工具栏中的 Profile 图标 在这里插入图片描述

二、内存泄露的排查方式

当通过正常启动应用或者通过如下方式启动应用后
在这里插入图片描述
会看到如下页面在这里插入图片描述
然后选择Memory选项卡进行双击打开,会看到如下页面
在这里插入图片描述
选择Capture heap dump。然后点击Record进行录制需要的功能。这个功能录制完会自动停止,然后停止后的页面如下(这个会自动停止好像跟之前的不太一样,不知道是不是升级后的改动)
在这里插入图片描述
可以看到最上层有Leaks的标志,表示内存泄漏数量。点击该位置后可以查看内存泄漏的位置
在这里插入图片描述
选择第一个内存泄漏的类双击后,然后保持和如图一直都页面,可以看到内存泄漏路径
在这里插入图片描述
有的信息比较浅显就能看出问题,有的则不能,比如第一个问题,暂时不知道该如何去排查问题。
而第二个类属于第三方库io.github.luoqqsh:immersionbar:3.1.0。查看使用方式时候发现其使用方式为

ImmersionBar.with(this).init()

该方式最终将activity持有在map集合里面,由于声明对象为静态类型,所以导致无法释放。暂时这个版本的库没法解决该问题。
第三个类的问题截图如下:
在这里插入图片描述
这里很好理解就是一个adListener里面的使用不当导致内存泄漏。代码如下
在这里插入图片描述
可以看到在异步加载结束后会更新View,但是加载结束后有可能页面销毁了,但是这里还持有context对象,就会导致内存泄漏。
第四个问题的截图如下:
在这里插入图片描述
没什么有太大价值的信息,只能看出是Fragment添加的时候有问题了,然后查看源码看看有没有添加Fragment的操作,好在源码简单,这是一个加载页面,只有一个fragment在里面添加了。
在这里插入图片描述
可以看出这个类跟内存泄漏的第五个类是一样的,所以是GoogleNativeInsertAd1Fragment的内存泄漏导致了ScanningFragment的泄漏。查看第五个类的问题
在这里插入图片描述
这里可以看出问题出在了NativeAdView(该控件属于admob的控件)上面,所以是这个控件使用不当导致的问题,顺便注意观察下整个调用链,会发现,这个调用链的顺序是从出现问题的地方逐步往外掉用,也就是说GoogleNativeInsertAd1Fragment中的控件导致了这个类泄漏,然后又引发了ScanningFragment的问题,最终导致了Activity的泄漏(这个节点未展开)。
至于最后一个的问题如下:
在这里插入图片描述
ReportFragment属于系统类还是隐藏的,不过这种问题也好解决,既然是系统类,那么一定有人已经遇见过了,直接网络搜索一下即可,如下例子:
Android 12原生系统居然有内存泄露隐患?
不过本文不再赘述该问题的解决方式,仅提供一个思路。本文的问题是为如何解决提供一个思路。每个项目逻辑不一样,所以泄漏方式也不一样。能做的只能尽可能去处理这些问题

三、参考链接

  1. 应用性能指南
  2. StrictMode
  3. Android Profiler

相关文章:

  • Linux 中的 ls 命令使用教程
  • anacoda 在 git 远程仓库的时候遇到 SSL 无法访问和字节缓冲太小和换源以及无法连接到官网和字节写入冲突
  • Linux——使用命令查看文件和文件夹数量
  • react项目自行配置热更新
  • 1-1、汇编语言概述
  • 【Python】巧用tkinter设计秒表计时器
  • linux下的工具---vim
  • 电力感知边缘计算技术网关产品设计方案-硬件方案
  • Kafka 集群如何实现数据同步
  • mysql使用--存储程序
  • 切换服务器上自己用户目录下的 conda 环境和一个外部的 Conda 环境
  • AMEYA360:村田首款1608M尺寸/100V静电容量1µF的MLCC实现商品化
  • 【Leetcode合集】1410. HTML 实体解析器
  • C语言键盘输入字符串小写转大写输出及scanf的小问题解决
  • 【MySQL】子查询
  • 2019年如何成为全栈工程师?
  • Apache Spark Streaming 使用实例
  • css选择器
  • Javascript Math对象和Date对象常用方法详解
  • JavaScript对象详解
  • Markdown 语法简单说明
  • miniui datagrid 的客户端分页解决方案 - CS结合
  • Vue ES6 Jade Scss Webpack Gulp
  • Vue 重置组件到初始状态
  • Vue官网教程学习过程中值得记录的一些事情
  • 大数据与云计算学习:数据分析(二)
  • 基于axios的vue插件,让http请求更简单
  • 技术:超级实用的电脑小技巧
  • 爬虫模拟登陆 SegmentFault
  • 为什么要用IPython/Jupyter?
  • Redis4.x新特性 -- 萌萌的MEMORY DOCTOR
  • 长三角G60科创走廊智能驾驶产业联盟揭牌成立,近80家企业助力智能驾驶行业发展 ...
  • ​猴子吃桃问题:每天都吃了前一天剩下的一半多一个。
  • # 飞书APP集成平台-数字化落地
  • #图像处理
  • (03)光刻——半导体电路的绘制
  • (09)Hive——CTE 公共表达式
  • (1) caustics\
  • (6)【Python/机器学习/深度学习】Machine-Learning模型与算法应用—使用Adaboost建模及工作环境下的数据分析整理
  • (C++)栈的链式存储结构(出栈、入栈、判空、遍历、销毁)(数据结构与算法)
  • (zhuan) 一些RL的文献(及笔记)
  • (八十八)VFL语言初步 - 实现布局
  • (附源码)php投票系统 毕业设计 121500
  • (简单有案例)前端实现主题切换、动态换肤的两种简单方式
  • (力扣记录)1448. 统计二叉树中好节点的数目
  • (力扣题库)跳跃游戏II(c++)
  • (万字长文)Spring的核心知识尽揽其中
  • (一)Thymeleaf用法——Thymeleaf简介
  • (转) SpringBoot:使用spring-boot-devtools进行热部署以及不生效的问题解决
  • (转)C#开发微信门户及应用(1)--开始使用微信接口
  • (转)chrome浏览器收藏夹(书签)的导出与导入
  • (转)nsfocus-绿盟科技笔试题目
  • . Flume面试题
  • .NET Micro Framework初体验(二)
  • .net 调用php,php 调用.net com组件 --