Android内存管理(12)*「实例」用Monitor 生成.hprof文件 并分析内存泄漏
参考
http://blog.csdn.net/xiaanming/article/details/42396507
基本步骤:
1,准备一个有内存泄漏的代码
mport android.os.Bundle;
import android.support.v7.app.AppCompatActivity; import java.util.ArrayList; public class InnerClassLeaksActivity extends AppCompatActivity { private ArrayList<String> list = new ArrayList<String>(); @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_inner_class_leaks);
//模拟Activity一些其他的对象
for (int i = ; i < ; i++) {
list.add("Memory Leak!");
}
//开启线程
new InnerClassHasLeak().start();
} public class InnerClassHasLeak extends Thread{ @Override
public void run() {
super.run();
//模拟耗时操作
try {
Thread.sleep( * * );
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
}
2,如何发现内存泄漏
- 打开 android-sdks/tools/monitor 工具
- 选中想要检测的程序,然后按 Update Heap
- 进入到想要检测的程序模块,点 Cause GC
- 旋转屏幕,每运行一会后再按一次 Cause GC 按钮。重复进入该模块执行旋转,GC。
Cause GC是手动产生一次GC清理下内存,如果多次GC后,可用部分内存变小,使用部分变多,说明有明显的内存泄漏。
如下图: 其中 Free变少,% Used变大 说明有内存泄漏。
3,生成.hprof
- 点击 Dump HPROF file 按钮生成 .hprof 文件
- 用 android-sdks/platform-tools/hprof-conv 工具 将生成的 xx.hprof 转为标准格式的 xxx.hprof
hprof-conv xx.hprof xxx.hprof
4,打开.hprof 文件开始分析
a,在打开.hprof 文件时,在向导页面选 Leak Suspects Report
b,在概述页面可以在全局角度查看内存使用情况
c,进入内存泄漏详细报告页面
注意其中的提示和 Keywords 部分.
其中Suspect 1 有两个 java.lang.Object[] 和 android.content.res.Resources ,本文检测第一个关键字。
d,生成柱状图
e,开始定位一个个可疑泄漏,在第一行 <Regex>中输入第一个关键字 java.lang.Object[]
f,在java.lang.Ojbect[]上 点 Merge Shortest Paths to GC Roots -> exclude all phantom/weak/soft etc.references
Merge Shortest Paths to GC Roots 可以查看一个对象到RC Roots是否存在引用链相连接, 在JAVA中是通过可达性(Reachability Analysis)来判断对象是否存活,这个算法的基本思想是通过一系列的称谓"GC Roots"的对象作为起始点,从这些节点开始向下搜索,搜索所走得路径称为引用链,当一个对象到GC Roots没有任何引用链相连则该对象被判定为可以被回收的对象,反之不能被回收,我们可以选择 exclude all phantom/weak/soft etc.references(排查虚引用/弱引用/软引用等)因为被虚引用/弱引用/软引用的对象可以直接被GC给回收.
g,可以看到LeakActivity存在GC Roots链,即存在内存泄露问题,可以看到 InnerClassLeaksActivity被 InnerClassHasLeak 的this$0持有。
除了使用Merge Shortest Paths to GC Roots 我们还可以使用
- List object - With outgoing References 显示选中对象持有那些对象
- List object - With incoming References 显示选中对象被那些外部对象所持有
- Show object by class - With outgoing References 显示选中对象持有哪些对象, 这些对象按类合并在一起排序
- Show object by class - With incoming References 显示选中对象被哪些外部对象持有, 这些对象按类合并在一起排序
5,修复代码
我们知道上面的例子代码中我们知道内部类会持有外部类的引用,如果内部类的生命周期过长,会导致外部类内存泄露,那么你会问,我们应该怎么写才不会出现内存泄露的问题呢?既然内部类不行,我们就外部类或者static的内部类,如果我们需要用到外部类里面的一些东西,我们可以将外部类Weak Reference传递进去
import android.os.Bundle;
import android.support.v7.app.AppCompatActivity; import java.lang.ref.WeakReference;
import java.util.ArrayList; public class InnerClassLeaksActivity extends AppCompatActivity { private ArrayList<String> list = new ArrayList<String>(); @Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_inner_class_leaks);
//模拟Activity一些其他的对象
for (int i = ; i < ; i++) {
list.add("Memory Leak!");
}
//开启线程
new InnerClassHasLeak().start();
} public class InnerClassHasLeak extends Thread{ @Override
public void run() {
super.run();
//模拟耗时操作
try {
Thread.sleep( * * );
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
public static class StaticInnerClassNoLeak extends Thread{
private WeakReference<InnerClassLeaksActivity> mLeakActivityRef; public StaticInnerClassNoLeak(InnerClassLeaksActivity activity){
mLeakActivityRef = new WeakReference<InnerClassLeaksActivity>(activity);
}
@Override
public void run() {
super.run();
//模拟耗时操作
try {
Thread.sleep( * * );
} catch (InterruptedException e) {
e.printStackTrace();
}
//如果需要使用LeakActivity,我们需要添加一个判断
InnerClassLeaksActivity activity = mLeakActivityRef.get();
if(activity != null){
//do something
}
}
}
}
不光 Thread有这个问题,Handler也有。
Android内存管理(12)*「实例」用Monitor 生成.hprof文件 并分析内存泄漏的更多相关文章
- Linux内存管理 (12)反向映射RMAP
专题:Linux内存管理专题 关键词:RMAP.VMA.AV.AVC. 所谓反向映射是相对于从虚拟地址到物理地址的映射,反向映射是从物理页面到虚拟地址空间VMA的反向映射. RMAP能否实现的基础是通 ...
- 在Mac中使用「dd」指令烧录ISO镜像文件到U盘
作者:超級efly 發布:2014-07-26 20:22 分類:電腦 閱讀:442 11條評論 大家在Windows系統下可以方便的使用UltraISO程式來燒錄「.ISO」, ...
- C++内存管理1-64位系统运行32位软件会占用更多的内存吗?
随着大容量内存成为电脑平台常规化的配置,在配置组装机时很多的用户都会选择8GB甚至是16GB的容量规格内存使用在自己的机器上,如果要将这8GB甚至是16GB的内容在系统使用时能充分利用起来的话,你平台 ...
- Android布局管理器-从实例入手学习相对布局管理器的使用
场景 AndroidStudio跑起来第一个App时新手遇到的那些坑: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/103797 ...
- 「一站式」兼容所有云厂商文件存储Spring Boot 实现
背景 在互联网发展的今天,近乎所有的云厂商都提供对象存储服务.一种海量.安全.低成本.高可靠的云存储服务,适合存放任意类型的文件.容量和处理能力弹性扩展,多种存储类型供选择,全面优化存储成本. 当我们 ...
- 「thunar」给thunar增加搜索文件功能
1.安装catfish sudo apt-get install catfish 2.配置thunar,添加[自定义动作] 打开 Thunar 后,点击 Edit -> Configure cu ...
- C学习笔记(11)--- 可变参数,浅谈内存管理 【C基础概念系列完结】
1.可变参数(variable arguments): 可变参数允许您定义一个函数,能根据具体的需求接受可变数量的参数. int func(int, ... ) (函数 fun ...
- Android内存管理机制
相信一步步走过来的Android从业者,每个人都会遇到OOM的情况.如何避免和防范OOM的出现,对于每一个程序员来说确实是一门必不可少的能力. 今天我们就谈谈在Android平台下内存的管理之道,开始 ...
- Android内存管理之道
相信一步步走过来的Android从业者,每个人都会遇到OOM的情况.如何避免和防范OOM的出现,对于每一个程序员来说确实是一门必不可少的能力.今天我们就谈谈在Android平台下内存的管理之道,开始今 ...
随机推荐
- poj 3744 Scout YYF I(递推求期望)
poj 3744 Scout YYF I(递推求期望) 题链 题意:给出n个坑,一个人可能以p的概率一步一步地走,或者以1-p的概率跳过前面一步,问这个人安全通过的概率 解法: 递推式: 对于每个坑, ...
- orcad中注意的事情
1.地的标识不能放到已经分配了网络的线上. 在用orcad画原理图的时候,把电源放到网络的时候需要特别的注意,如果,将电源地直接放到线上,而这根线又已经被分配了网络标号,那这个地会随已经分配了的网络号 ...
- 【Codeforces 382C】Arithmetic Progression
[链接] 我是链接,点我呀:) [题意] 让你在n个数字中再加入一个数字 使得这n+1个数字排序之后 相邻两个数字的差都相同 [题解] 注意相邻为0的情况 这种情况 只有全都相同才行 只有一种情况 然 ...
- CF899F. Letters Removing
给一个字符串支持以下操作:区间删除某个特定字符.最后输出字符串.n,m<=200000. 这题我居然不会可以回家了.. 首先,单点删除,选个平衡树比如set. 然后,他给的下标是会随删除操作变化 ...
- 总结for循环及for循环增强遍历数组,list,set和map
一.对于集合 (1)普通for循环 int[] arr = { 2, 1, 2 }; for(int i=0;i<arr.length;i++){ System.out.println(arr[ ...
- Xdebug的安装、配置和使用
对于我这么一个渣渣php码农,平时总觉得echo.var_dump.print_r就能满足我的调试需求了,最近公司开始一个新项目,要大量阅读调试旧的源码,echo和var_dump开始不够用了,于是装 ...
- Ubuntu 16.04下UML建模PowerDesigner的替代ERMaster和MySQL Workbench
ERMaster是Eclipse的一个插件,小巧,支持连接各种数据库,还能生成代码等.安装参考:http://www.cnblogs.com/EasonJim/p/6170686.html 当然还有一 ...
- Eclipse代码/目录虚线对齐设置
前提: 我的Eclipse版本如下: 比这个版本新或者旧都可以实现如下效果. 实现步骤: 在代码上显示虚线设置有如下方法: 1.如果不使用插件,Eclipse是不支持虚线的,只能是横条的点状,效果如下 ...
- 使用 IAsyncResult 调用异步方法
.NET Framework 和第三方类库中的类型可以提供允许应用程序在主应用程序线程之外的线程中执行异步操作的同时继续执行的方法.下面几部分介绍了在调用使用 IAsyncResult 设计模式的异步 ...
- 【Storage】IBM DS8100开机及配置过程
************************************************************************ ****原文:blog.csdn.net/cla ...