内存泄漏面面谈

概述

主要介绍了内存泄漏的关注点是对象,对内存问题进行了分类并且确定本文关注点是内存泄漏,15种内存泄漏判断方式,hprof文件的用法和分析过程,以及memory profiler工具一些基本概念,最后提到了如何触发内存泄漏问题

内存泄漏的关注点——对象占据的内存

  • 本该回收的对象,无法被垃圾处理器回收;
  • 程序不再使用的对象,无法被垃圾处理器回收;
  • 在页面生命周期销毁后,页面持有、创建过的对象无法被垃圾处理器回收;
  • 在任务(线程、Service、广播)结束后,任务持有、创建过的对象无法被垃圾处理器回收

Android内存问题概述

内存抖动的表现形式:

  1. 忽高忽低,锯齿状

内存泄漏的表现形式:

  1. 页面或任务已经结束,相关的对象仍然被GC root索引,导致垃圾回收器无法回收,内存片段仍然存在

内存溢出的表现形式:

  1. App可用内存已到达系统规定的上限,如X型号手机规定单个App最大可分配内存为196mb
  2. 系统能为App分配的内存不足,系统可分配内存已经到达上限,如系统可用只有1mb,app需要20mb

Android中内存泄漏的判断方式

判断一个对象是否无法被回收,最佳的判断方式是定义清楚这个对象预期的生命周期,通常对象是随着页面、任务的生命周期产生和消亡的,Android中可以借此机制判断是否存在泄漏现象:
PS:“是否存在于hporf文件里”,是笔者用于等价替换原文“未被回收”的字样

  1. Activity:通过查看Activity#mDestroyed属性来判断Activity是否已经销毁,如果为true,表明该Activity已经被标记为销毁状态,此时hprof文件中若仍然存在此Activity,则表明这个Activity占据的内存处于泄漏状态;
  2. Fragment:通过Fragment#mFragmentManager属性来判断该Fragment是否处于无用状态,如果mFragmentManager为空,且hprof文件中若仍然存在此Fragment,则表明Fragment占据的内存处于泄漏状态;
  3. View:通过un wrapper#mContext获得Activity,如果Activity不为空,则按照判断Activity的方式判断Activity是否泄漏
  4. ContextWrapper:通过unwrapper ContextWrapper获得Activity,如果Activity不为空,则按照判断Activity的方式判断Activity是否泄漏
  5. Dialog,通过判断mDecor是否为空。mDecor为空,表明Dialog处于不被引用的状态,mDecor仍然存在在hporf里且为空,则表明Dialog泄漏了
  6. MessageQueue:通过判断MessageQueue#mQuitting或mQuiting是否退出,如果该值是true且未被回收,则认为是泄漏。
  7. ViewRootImpl:通过ViewRootImpl是否为空来判断,为空表明处于无用状态,为空且未被回收则被认为是泄漏
  8. Window:通过Window#mDestroyed来判断window是否处于无用状态,mDestroyed为true且未被回收,则认为是泄漏
  9. Toast:拿到mTN,通过mTN#mView是否为空来判断当前Toast是否已经hide,如果mView为空,表明Toast已经hide,此时Toast未被回收则认为是泄漏
  10. Editor:Editor是用于TextView处理editable text的辅助类,通过ditor#mTextView为空来判断Ediator是否处于无用状态;如果mTextView为空且未被回收则认为Editor泄漏了
    内存泄漏的典型 场景
  11. 非静态内部类、匿名内部类持有外部类对象的引用:常见的如Listener、CallBack、Handler、Dialog
  12. 非静态的Handler,持有Activity,Message持有Handler,Message被MessageQueue持有,MessageQueue持久存在,导致Activity不会被释放
  13. 资源对象未关闭:数据库连接、Cursor、IO流使用完后未close
  14. 属性动画:未及时使用cancel关闭;Animator持续存在,导致Animator持有的Activity、Fragment、View泄漏(Animator#updateListener一般都是匿名内部类,匿名内部类的问题参考场景1)
  15. 逻辑问题:广播监听后未及时解注册;

Hprof文件

Hprof文件导出

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

Heap分区:

  1. app heap:当前App在堆中占据的内存
  2. image heap:系统启动镜像,包括启动期间预加载的类
  3. zygote heap:所有App的父进程,所有App共享zygote的内存空间,zygote预加载了许多资源和代码,供所有App读取

Instance View:

  1. depth:从gc root到当前对象的引用链最短深度。被gc root引用到的对象不会被回收。
  2. 个人收获:depath = 0,表示不被gc root引用,即会被垃圾回收器回收。
  3. 个人收获:常见gc root有5种——局部变量、Activity threads、静态变量、JNI引用、类加载器
  4. native size:native对象占据的内存大小
  5. shallow size:对象本身占用的内存,何为对象本身?不包括它引用的其他实例
  6. 个人收获:shallow size = 类定义+ 父类变量所占空间大小 + 类成员变量所占空间 + [ alignment]
  7. 类定义:固定为8Byte
  8. 父类变量所占空间大小:当前类继承了其他类的成员变量,显然这些变量是占用空间的
  9. 自身变量:当前类的成员变量,如果是基本数据类型,则按基本类型计算;如果是引用数据类型,则固定为4byte,当前类仅持有变量名,
  10. alignment:指位数对齐,目的是让shallow zie的值为8的倍数,如某个类A,前三项计算结果未15byte,则shallo size为了达到8的倍数,会设置一个alignment值,凑够16byte。
  11. retained size:Retained Size是指, 当实例A被回收时, 可以同时被回收的实例的Shallow Size之和

Instance View易混淆概念:

shallow size:
Shallow Size是指实例自身占用的内存, 可以理解为保存该’数据结构’需要多少内存, 注意不包括它引用的其他实例
retained size:
实例A的Retained Size是指, 当实例A被回收时, 可以同时被回收的实例的Shallow Size之和
在这里插入图片描述
图中A, B, C, D四个实例, 为了方便计算, 我们假设所有实例的Shallow Size都是1kb
删除D实例:垃圾回收期会移除D实例;D实例的Retained Size=Shallow Size=1kb
删除C实例:垃圾回收器会移除C和D实例;C实例的Retained Size = C实例的Shallow Size + D实例的Shallow Size = 2kb
删除B实例:垃圾回收器会移除B实例,因为C仍然被A引用,所以C不会被移除,同理D也不会被移除;B实例的Retained Size=Shallow Size=1kb
删除A实例:垃圾回收器会移除B、C、D实例;A实例的Retained Size=4kb

怎么从prof文件内分析内存泄漏?

熟能生巧——memory profiler

实时预览功能区:

在这里插入图片描述

Hprof文件预览区:

在这里插入图片描述

怎么触发泄漏

  1. 旋转屏幕
    在不同的 activity 状态下,先将设备从竖屏旋转为横屏,再将其旋转回来,这样反复旋转多次。旋转设备经常会使应用泄漏 Activity、Context 或 View 对象,因为系统会重新创建 Activity,而如果应用在其他地方保持对这些对象其中一个的引用,系统将无法对其进行垃圾回收。
  2. 切换App至前台
    在不同的 Activity 状态下,在应用与其他应用之间切换(导航到主屏幕,然后返回到您的应用)。
  3. 断开后链接网络
  4. 锁屏后亮屏
  5. 频繁操作
    1. 频繁点击按钮,如编辑用户信息,点击保存按钮,触发保存业务
    2. 频繁进入页面,如重复进入-退出某个页面
    3. 频繁刷新页面,如重复下拉加载更多

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

C# 读取 CSV 文件的方法汇总

文章目录 1. 使用System.IO命名空间中的类2. 处理标题行和指定列3. 使用CsvHelper库4. 高级功能和异常处理5. 使用 LINQ6. 总结 CSV(Comma-Separated Values,逗号分隔值)文件是一种简单的文本文件格式,用于存储表格数据。在C#中&a…

关于pdfbox读取pdf

最近,想着将pdf的文件进行读取其内容,发现了一个比较好用的依赖pdfbox。目前使用这个依赖,进行实现一个简单实例,如果之后需要使用到更深的了解,会进行更新。这里提醒一下:jdk8尽量采用pdfbox3.x版本。 对…

磁珠笔记汇总

磁珠笔记汇总 磁珠是和电感很相似的器件。 电感磁珠单位亨(H)欧姆(Ω)是否储能存储能量消耗高频能量应用场景通常用于开关电源吸收高频,EMC保护如何看待损耗使用电感时希望损耗越小越好使用磁珠时是利用其损耗来消耗不需要的高频分量 一、磁珠的工作原理 磁珠与…

代码随想录——左叶子之和(Leetcode404)

题目链接 BFS 队列 /*** Definition for a binary tree node.* public class TreeNode {* int val;* TreeNode left;* TreeNode right;* TreeNode() {}* TreeNode(int val) { this.val val; }* TreeNode(int val, TreeNode left, TreeNode right)…

FreeRTOS_信号量_学习笔记

信号量的特性 消息队列用于传输多个数据,但是有时候我们只需要传递状态,这个状态值需要用一个数值表示。套用队列笔记中的流水线例子,可以理解为流水线上工件的数量。 信号:起通知作用 量:还可以用来表示资源的数量 当…

SNP数据转型解析:云服务在现代企业数字化转型的必要性

为什么当今的企业想为数字化工作环境做好准备并保持竞争力,很难避免使用云服务呢? 要理解为什么企业没有云的替代选择,我们需要了解云服务的含义 - 它不仅仅指存储数据的另一个位置。各种云模型提供了极大的灵活性,可以根据需要操…

安卓开机启动阶段

目录 概述一、boot_progress_start二、boot_progress_preload_start三、boot_progress_preload_end四、boot_progress_system_run五、boot_progress_pms_start六、boot_progress_pms_system_scan_start七、boot_progress_pms_data_scan_start八、boot_progress_pms_scan_end九、…

Linux:IPC - System V

Linux:IPC - System V 共享内存 shm创建共享内存shmgetshmctlftok 挂接共享内存shmatshmdt shm特性 消息队列 msgmsggetmsgctlmsgsndmsgrcv 信号量 semSystem V 管理机制 System V IPC 是Linux系统中一种重要的进程间通信机制,它主要包括共享内存 shm&am…

[RK3588-Android12] 关于ES8388 喇叭+PDM回采 4+2配置

问题描述&#xff1a; ES8388 喇叭PDM回采 42配置如下&#xff1a; 解决方案&#xff1a; // MICpdmics: dummy-codec {status "okay";compatible "rockchip,dummy-codec";#sound-dai-cells <0>;};// MICpdm_mic_array: pdm-mic-array {status …

“一带一路”六国国际拳王冠军赛特克斯站新闻发布会顺利举行

实习记者&#xff1a;喀兰姆罕 5月24日&#xff0c;“一带一路”六国国际拳王冠军赛特克斯站新闻发布会在特克斯县阿克塔斯姑娘峰景区举行。这次拳王冠军赛事由新疆广播电视台、特克斯镇人民政府&#xff0c;特克斯县文化体育广播电视和旅游局主办&#xff0c;将于6月15日在特…

设计模式18—— 迭代器模式

写文章的初心主要是用来帮助自己快速的回忆这个模式该怎么用&#xff0c;主要是下面的UML图可以起到大作用&#xff0c;在你学习过一遍以后可能会遗忘&#xff0c;忘记了不要紧&#xff0c;只要看一眼UML图就能想起来了。同时也请大家多多指教。 迭代器模式&#xff08;Iterat…

vue系列之 插槽(Slot) 详解

插槽在vue中是一种很常见的写法&#xff0c;让父组件可以向子组件指定位置插入html结构&#xff0c;也是一种组件间通信的方式。一共有三种分类&#xff1a;默认插槽、具名插槽、作用域插槽&#xff0c;下面一一结合案例详细说明。原创不易&#xff0c;需要的小伙伴 收藏关注 哦…

最新斗音评论区截流拓客,自动引流【引流软件+使用教程】

面对社交媒体的蓬勃生长&#xff0c;加粉和拓展客户群成为品牌及个体的当务之急。新推出的一款技术工具恰到好处地迎合了这一需求&#xff0c;提供了一个多功能、适用性强的增粉与互动解决方案。该工具与抖音平台的所有版本兼容&#xff0c;消除了对特定版本的依赖。 利用这一…

浅揭秘:Java方法调用过程中栈内存到底干了什么

在深入Java编程的世界时&#xff0c;理解其方法调用背后的内存管理机制是至关重要的。 Java作为一种面向对象的语言&#xff0c;其内存管理自动化程度高&#xff0c;但背后涉及的原理却错综复杂&#xff0c;尤其是方法调用过程中的栈帧、堆、方法区等概念。 本文将通过代码示…

【实用的 IDEA 配置和操作技巧总结】

前置知识 IDEA的设置快捷键为ctrlalts键&#xff0c;后文介绍IDEA常见的配置就不再赘述这一点了。 基础配置 取消默认打开上次项目 日常开发都会打开不同的项目&#xff0c;初次安装IDEA之后&#xff0c;每次打开IDEA都会开启上一次启动的项目&#xff0c;所以我们需要进入设…

话术巧妙分隔沟通效果更佳看看这个小技巧

客服回复客户咨询&#xff0c;如果遇到比较复杂的问题&#xff0c;经常会有大段的文字回复&#xff0c;用聊天宝的分段符功能&#xff0c;在需要分段的地方点击右上角的“插入分隔符”&#xff0c;就可以在指定位置分段&#xff0c;实现多段发送的目的。 前言 客服回复客户咨询…

NSS‘题目练习3

[SWPUCTF 2021 新生赛]easyupload3.0 打开题目发现要求上传.jpg文件 先上传抓包&#xff0c;尝试更改后缀 换一种形式 文件头绕过 都试过之后尝试上传.htaccess文件&#xff0c;发现上传成功 会将之后上传的文件后缀自动更名为.php 再上传.jpg文件 蚁剑连接找到flag [SWPUCTF …

读书短视频脚本:四川京之华锦信息技术公司

读书短视频脚本&#xff1a;打造引人入胜的文学世界 随着短视频平台的兴起&#xff0c;各类内容以更加直观、生动的方式呈现在观众面前。在这个信息爆炸的时代&#xff0c;如何将书籍的精华和魅力通过短视频这一新兴媒介传递给更多人&#xff0c;成为了一个值得探讨的话题。四…

部署CNI网络组件+k8s多master集群部署+负载均衡

一、环境部署 主机服务 192.168.91.5 K8S集群master01192.168.91.8 K8S集群master02192.168.91.6K8S集群node01192.168.91.7K8S集群node02192.168.91.9 负载均衡nginxkeepalive01&#xff08;master&#xff09;192.168.91.10 负载均衡nginxkeepalive02&#xff08;backup&am…

港口与航运3D三维虚拟仿真展区让更多人了解到海洋知识

在短短20天内&#xff0c;搭建起200多家线上3D展厅&#xff0c;听起来似乎是一项艰巨的任务。然而&#xff0c;对于我们的3d云展平台而言&#xff0c;这早已成为常态。连续三年&#xff0c;我们已成功为众多会展公司在短时间内构建出几百家甚至上千家的线上3D展会&#xff0c;见…