Android内存泄漏检测工具大全

news/2024/12/28 12:53:19/

什么是内存泄漏?


  简单理解:没有被GC ROOT直接或者间接引用的对象的内存回收掉


性能优化就得考虑使用工具进行检测,Android关于内存工具很多,要能够定位剖析问题。但是会有写场景不会覆盖到,只能发现问题的能力工具。整合下基本使用到的工具。


top/procrank
STRICTMODE(楼主没有使用过)
MAT、Finder
meminfo
LeakCanary
LeakInspector
APT(腾讯开源:https://code.csdn.net/Tencent/apt/tree/master)
Allocation Tracker
Chrome Devtool 
Systrace
Android Architecture Components

 

 


top/procrank

对于此工具来讲,需要知道几个名词含义:


VSS    Virtual Set Size       虚集合大小 
RSS    Resident Set Size      常驻集合大小 
PSS    Proportional Set Size  比例集合大小
USS    Unique Set Size        独占集合大小 

 

  RSS 与 PSS 差不多,包含进程共享内存,RSS没把共享内存大小平分到使用共享的进程上,所以所有进程的RSS相加会超过物理内存。 
  VSS是虚拟地址,它上线与进程的可访问地址有关,和当前进程的内存关系不大。 
  PSS包含进程间共享的内存,而USS不包括,进程USS相加小于物理内存大小的原因。对于PSS而言,如果A进程和B进程同时共享同一个SO库,那就平分到了A和B上,但启动A进程,B没有启动,则B的PSS曲线图会有较大的阶梯状下滑。对于USS而言,它的坑在Dalvik申请内存会有GC延时及其策略,会影响曲线波动。
  
  
  VSS >= RSS >= PSS >= USS

 

 


meminfo

 


  使用dumpsys meminfo 命令 
  用法: dumpsys meminfo options:[-a][–oom][process] 
  -h帮助信息 
  -a打印所有进程的内存信息,以及当前设备的内存概况 
  –oom 按照OOM Adj值进行排序。 
  [Process]进程名,也可以是id 
  比如:dumpsys meminfo | grep -i phone,查 phone相关进程。 
  watch -n 5 dumpsys meminfo com.android.phone 每隔5秒刷新一次

 

 


Procsatats

 


  要提到一个公式:内存负载 = PSS X 运行时长 
  内存负载在Android4.4上提出来(App在手机设备上显示一样),分为:前台,后台,缓冲负载。 
  前台,用户当前使用的,用户不关注的,内存负载不应该默认显示。 
  后台,是app行为,系统无权kill掉并回收,并非用户当前所使用,被默认展示。 
  缓冲,可以回收,内存负载不应该默认展示,没有被杀死是软件的恢复能力,是系统的责任。

 

 


DDMS

 

 

(Dalvik Debug Monitor Server)

 


  各种调试信息集合,有时延,内存,线程,cpu等各种信息展示,经常使用Heap、Allocation Tracker 和 Dump Hprof file(内存快照)。

 

Update Heap获取GC信息,当前已分配内存,当前运行的对象,所剩内存,动态虚拟机heapSize,及其分布柱状图
Allocation Tracker , 展示了500条的内存分配,相关的线程堆栈信息。申请的内存大,GC就多,GC会挂起全部线程,会导致卡顿现象。
Dump Hprof file,选中进程,进行内存快照,Android Studio上有此功能。

 


MAT


  全称:Memory Analyzer(内存分析),需要抓取Hprof文件,最简单使用ddms抓取,其次就是命令


抓取hprof命令如下(在adb shell模式下): 


am dumpheap pid outfilePath (文件名必须为hprof)

 


 

操作:(DDMS抓取的可以直接忽略转格式问题) 
1. adb shell am dumpheap  com.android.phone   /data/local/tmp/test.hprof 
2. adb pull /data/local/tmp/test.hprof c:\test.hprof 
3. hprof-conv c:\test.hprof c:\testConv.hprof

 

Finder


Activity  获取dump的所有Activity对象 
Top Classes  对象数量或对象大小为维度来获取对象降序列表
Compare  对比两个Hprof文件内容的差别
Bitmap 获取dump的所有bitmap对象
Same Bytes 查询dump 中以byte[]类型出现并且内容重复的对象 
Singleton 查询dump中的单例


能够准确定位80%的泄漏问题 

 

LeakCanary


  – 在onDestory 时检查弱引用,使用ReferenceQueue,白名单需要写死在AndroidExcludedRefs.java中。每次得重新编译,区分系统版本。
  
  – 能识别系统泄漏,能够给出一个分析。
  
  – 需要人工修复解决内存泄漏问题 
  
  – 使用开源组件HAHA 分析(参考简书),返回一条GC链。

 


LeakInspector


  – 在onDestory 时检查弱引用,使用WeakReference,提供回调方法,能增加自定义的LOG,TRACE,DUMPSYS信息,需要在白名单以XML配置的形式存放到服务器上,不区分系统版本。
  
  –  可以进行预处理,在ondestroy里,通过反射自动修复系统泄漏。
  
  – 可以对对整个Activity的View遍历一遍,把图片所占用的内存数据释放掉,能够减少对内存的影响
  
  – 采集dump后,自动通过Magnifier上传dump文件,调用MAT命令进行分析,返回GC链。
  
  – 可以跟自动化测试无缝结合,自动化脚本执行过程中发现内存泄漏,收集dump发送到服务器上,分析,生成JSON结果。

 


JHat


  Oracle公司开发的多人协作Hprof分析工具
  
  使用命令:jhat test.prof
  
  解析prof文件,开启httpSrv服务,维护解析后的数据,默认端口7000,直接访问查询。

 


libc_malloc_deBug_leak.so库


  Android系统底层调用libc.so申请内存,而libc_malloc_deBug_leak库就是监视libc.so内部接口的调试库
  
  Native Heap 就是类内存申请部分,NDK编译出来的so文件放到系统的 /data 目录中,size字段的值就是内存大小,每一个都拥有一个申请的调用栈,根据栈后的method字段值能够知道该方法的内存偏移,使用addr2line.exe转化方法名称,注需要编译选项中加入“-Wl,-Map=xxx,map -g”

 


APT


  腾讯开源的测试工具,是DDMS的插件,能够实时监控多个app的cpu及其内存情况,以图表形式展示出来
  
  参考官方

 


GC Log


  Logcat输出的log日志,分为Dalvik Log和ART Log两种

 

Dalvik GC Log


GC 产生原因:


GC_EXPLICIT : 通过Runtime.gc()与VMRuntime.gc(),SIGUSR1触发产生GC,支持并发GC,列表滑动,动画播放,不要有这种Log,高CPU低响应时延不要人工触发GC。
GC_FOR_[M]ALLOC : 没有空闲内存空间给要分配的内存,不是并发GC,会有卡顿,尽量避免。
GC_FOR_CONCURRENT : 当超过堆占用阀值时会触发,局部的并发GC 。
GC_BEFORE_OOM : 在出发OOM前触发的GC,不能局部并发,耗时长,会卡顿。
GC_HPROF_DUMP_HEAP : 在dump内存前触发GC,不能局部并发,耗时长,会卡顿。

 

  查看工具:Dalvik GC Log 绘制成图表的工具

 

ART GC Log


GC 产生原因:


GC_EXPLICIT : 通过Runtime.gc()与VMRuntime.gc(),SIGUSR1触发产生GC,支持并发GC,列表滑动,动画播放,不要有这种Log,高CPU低响应时延不要人工触发GC。
GC_FOR_[M]ALLOC : 没有空闲内存空间给要分配的内存,不是并发GC,会有卡顿,尽量避免。
GC_FOR_CONCURRENT : 当超过堆占用阀值时会触发,局部的并发GC 。
NativeAlloc : Native内存不足以分配内存时触发。
Background : 后台GC,给后面的内存申请预留空间。


GC 类型:


Full : 跟Dalvik 的Full一样
Partial: 跟Dalvik局部GC一样,没有Zygote Heap策略
Sticky 局部中的局部GC ,上次垃圾回收后新分配的对象。


GC 的三种方式:


mark sweep : 记录全部对象,从GC ROOT中找出直接或间接的对象做标注,利用之前记录的全部对象和标注对象做对比,剩余的便是要回收的。
concurrent mark sweep :  使用mark sweep的并发GC
mark compact : 对所有活动的对象压缩到内存的一侧,另外一侧进行回收。
semispace : 把所有引用的对象从一个空间放到另外一个空间,剩余在旧空间的对象就是要直接GC掉的。

 


Allocation Tracker


  Android Studio 里打开Monitor,选择要查看的进程,选择Allocation Tracker,录制出结果按照Size排序,能够直接通过dump to source跳转到对应代码行。  

 


Chrome Devtool


  需要安装Chrome浏览器,移动端和PC端,PC 端访问Chrome://inspect ,点击调试页面下的inspect,出来开发者工具
  
  官方中文文档

 


Systrace


  Android4.1上引入的性能分析工具,能够输出各个线程的当前函数调用状态,并且可以跟当前CPU的线程运行状态、VSYNC、SurfaceFlinger等系统信息在同一时间轴上进行对比。但不是所有手机机型都能支持。
  
  SurfaceFlinger服务在每个VSYNC信号中断时调用一次,那APP显示非常流畅。
  
  如果VSYNC的上升沿SurfaceFlinger服务没有调用,那会导致丢帧。 
  (1) CPU负载过大,低端机型的单核机型上会有发生。在VSNYC中断信号处,CPU闲暇,没有执行其他进程任务时,那我们需要做进一步分析 
  (2) 应用侧没有完成绘制,应用内部处于繁忙时,查看performTraversals信息,忙于其他业务逻辑没有绘制,那看是否忙于分发响应事件。如果当前窗口视图太多,布局嵌套太深,会导致查找响应输入事件的控件耗时长,没法绘制UI。
  
  对于绘制等问题,Google添加了一些警告; 
  (1) Inefficient View alpha usage(5.1+以上才有)
  
  (2) Expensive rendering with Canvas.saveLayer()
  
  
    Canvas.saveLayer()会打断绘制过程中的渲染管道,替换使用View.LAYER_TYPE_HEARDWARE或者static Bitmaps,会让离屏缓存服用相邻两帧间的数据,避免渲染目标被切换而打断。
  
  
  (3) Path Texture Churn
  
  (4) Expensive Bitmap uploads
  
  
    Bitmaps 在硬件加速下,修改和图像的变化都会上传给GPU,如果像素总量大,会消耗GPU的较大资源,所以建议减少每帧中对图片的修改,出现调用setLayerType为LAYER_TYPE_SOFTWARE之后,此时整个屏幕变成一张图。
  
  
  (5) Inflation during ListView recycling
  
  
    没用ListView复用,造成inflate的单个Item的getView成本比较高
  
  
  (6) Inefficient ListView recycling/rebinding
  
  
    每帧的ListView recycling 耗时较长,那得看下Adapter.getView()绑定数据的时候是否存在问题
  
  
  (7) Expensive Measure/Layout pass
  
  
    Measure / Layout 耗时导致卡顿,动画时,不要触发Layout
  
  
  (8) Long View.draw()
  
  
    Draw 本身耗时比较长,避免在View 或 Drawable 的onDraw里面执行任务频繁自定义操作,特别时申请内存和绘制Bitmap.
  
  
  (9) Blocking Garbage Collection
  
  
    GC导致卡顿,就是GC for Alloc的stop the world,避免在动画的时候生成对象,尽量重用Bitmap能够避免触发GC。
  
  
  (10) Lock contention
  
  
    UI 线程锁,UI线程去使用其他线程持有的锁,检查现有UI线程锁并确认它锁住的时间长短。
  
  
  (11)  Scheduling delay
  
  
    网络I/O、磁盘I/O 等线程资源争抢,导致有一定时间的UI线程实际耗时长,而卡顿,检查后台线程是否都云溪nag在低优先级的线程上(是否比Thread_Priority_background还低)。
  

 


Android Architecture Components


  Android 架构组件
  
  存储数据,管理生命周期,模块化,避免常见错误,减少样板文件
  
  
    Lifecycles
  
  
  每个 Android 开发者都应该面对过生命周期问题,即操作系统启动、停止和销毁 Activity。这意味着开发者需要根据生命周期的不同阶段,有针对性地管理组件状态,比如用于更新用户界面的可观察对象。生命周期管理(Lifecycles)帮助开发者创建 “可感知生命周期的” 组件,让其自己管理自己的生命周期,从而 减少内存泄露 和崩溃的可能性。生命周期库是其他架构组件(如 LiveData)的基础。
  
  
    LiveData     
  
  
  LiveData 是一款基于观察者模式的可感知生命周期的核心组件。一种可观测数据容器,它会在数据变化时通知观测器,以便更新界面。
  
  LiveData 为界面代码 (Observer)的监视对象 (Observable),当 LiveData 所持有的数据改变时,它会通知相应的界面代码进行更新。同时,LiveData 持有界面代码 Lifecycle 的引用,这意味着它会在界面代码(LifecycleOwner)的生命周期处于 started 或 resumed 时作出相应更新,而在 LifecycleOwner 被销毁时停止更新。通过 LiveData,开发者可以方便地构建安全性更高、性能更好的高响应度用户界面。
  
  有两个对应接口,LifecycleOwner和LifecycleObserver; 
  LifecycleOwner是具有生命周期的对象,比如Activity和Fragment. 
  LifecycleObserver观测LifecycleOwner,并在生命周期变化时收到通知。
  
  
    ViewModel     
  
  
  ViewModel 将视图的数据和逻辑从具有生命周期特性的实体(如 Activity 和 Fragment)中剥离开来。直到关联的 Activity 或 Fragment 完全销毁时,ViewModel 才会随之消失,也就是说,即使在旋转屏幕导致 Fragment 被重新创建等事件中,视图数据依旧会被保留。ViewModels 不仅消除了常见的生命周期问题,而且可以帮助构建更为模块化、更方便测试的用户界面。
  
  
    Room
  
  
  一款简单好用的SQL对象映射库。它和 SQLite 有一样强大的功能,但是节省了很多重复编码的麻烦事儿。它的一些功能,如编译时的数据查询验证、内置迁移支持等,更简单地构建健壮的持久层。而且 Room 可以和 LiveData 集成在一起,提供可观测数据库并感知生命周期的对象。Room 集简洁、强大和可靠性为一身,在管理本地储存上表现卓越。
  
  
    PagedList
  
  
  解决用 RecyclerView 处理大数据集的困难。
  
  App 架构指南 
  Android 架构组件官网

 

 


参考博客地址:

开源项目之LeakCanary源码分析: http://www.jianshu.com/p/5032c52c6b0a

查找并修复Android中的内存泄露—OutOfMemoryError: 
https://yq.aliyun.com/articles/40294

内存分析工具 MAT 的使用 :  
http://blog.csdn.net/aaa2832/article/details/19419679

Android 查看内存使用工具 (procstats): 
http://blog.csdn.net/vshuang/article/details/51755756

Android进程内存统计工具procstats: 
https://wenku.baidu.com/view/c8d49549b90d6c85ed3ac63b.html
--------------------- 
作者:jink_l 
来源:CSDN 
原文:https://blog.csdn.net/superloveboy/article/details/78536750 
版权声明:本文为博主原创文章,转载请附上博文链接!


http://www.ppmy.cn/news/170650.html

相关文章

内存带宽性能测试工具

一、STREAM软件是内存带宽性能测试的基准工具,也是衡量服务器内存性能指标的通用工具。STREAM软件具有良好的空间局部性,是对转换检测缓冲区TLB(Translation Lookaside Buffer)友好、缓存友好的一款软件。STREAM软件支持复制&…

查看计算机内存条型号,查看本机内存条型号_查看电脑内存条型号

2017-01-05 14:28:15 首先在电脑上安装鲁大师,鲁大师可以在360中直接添加的,也可以去百度里搜索一下的。打开鲁大师,开始进行硬件检测,等待检测完成。点击左侧的内存信息,这时你会看到你的内存条的型号等信息... 2016-12-09 12:45:22 有很多方法1,内存条上面有标签上面就…

ndows 内存诊断工具,Windows自带内存诊断工具来帮你检测电脑内存的稳定

大象网写这篇文章的原因是自己遇到了内存的问题,记忆尤新的是2014年给亲戚组装的一台台式机,大概配置就是下面这样,翻了半天电脑上的配置好不容易找到这台电脑。 Intel 酷睿i3 3220(散) 华擎B75M-DGS R2.0 金士顿4GB DDR3 1600 希捷 Barracuda 500GB 7200转 16MB SATA3 HIS …

测试内存条是否兼容软件,18款内存条兼容性测试

在内存条件兼容性测试方面我们除了使用939接口的主板进行测试之外,还使用了462、LGA775以及478接口支持DDR内存的主板进行测试。 因为市售主板品牌较多,如果按照每个品牌主板都进行测试一遍的话将会给本次测试带来很大的工作压力,因此经过讨论…

Java内存泄漏检测工具 JRockit Memory Leak Detector

内存泄漏检测工具 还有其他的专门进行内存泄漏检测的工具。JRockit Memory Leak Detector可以用来查看内存泄漏,并可以更深入地查出泄漏的根源。这个强大的工具是紧密集成到JRockit JVM中的,其开销非常小,对虚拟机的堆的访问也很容易。 专业…

什么软件可以测试内存条稳定性,内存检测就这么简单,学会这几个软件就可以了...

原标题:内存检测就这么简单,学会这几个软件就可以了 升级内存条应该是整个DIY过程中最简单易上手的,为什么会这么说呢?如果机械硬盘换SSD,升级系统可能会难倒一片,当然这些对于我这个老司机来说都是小CASE。 今天不介绍怎么安装系统,主要说一说这一次升级内存的一些事,…

Linux 内存性能检测工具

本文介绍关于Linux系统的内存带宽测试工具-mbw。内存性能测试工具包括: 内存带宽测试工具——mbw; 内存压力测试工具——memtester; 内存综合性能测试工具——lmbench; 内存申请(顺序/随机)与&#xff0…

台式机内存测试软件中文版,内存检测工具 MemTest

MemTest是可靠的内存检测工具,通过对电脑进行储存与读取操作来分析检查内存情况。内存检测工具 MemTest不但可以彻底的检测出内存的稳定度,还可同时测试记忆的储存与检索资料的能力,让你可以确实掌控到目前你机器上正在使用的内存到底可不可信赖 。如果你刚购置了硬盘或者电…