❶ android 分析OOM工具介绍
如图1所示, 步骤
** 1, 2, 3** 为打开Android Monitor并切换标签到monitor的过程
4, 5, 6 对应的图标和文字含义分别是
MAT 工具识别,并解析hprof文件,
有两种方式可以获得hprof文件
MAT并不能直接打开这两个hprof, 必须通过hprof-conv来转换一次
如图3所示,选中(过滤出MainActivity), 然后通过Objects可以看出它有8个实例
接着选中 com.example.wowo.MainActivity 然后右键选择
Merge shortest paths to GC Roots -> exclude week references
因为弱引用是会被回收的,所以排除掉更加容易发现OOM.
什么是OOM out-of-memory?
Android下的APP运行在VM中(Dalvik or ART), 一个APP需要的内存是有限,这个值在不同的平台, 不同的手机上是不同的,当APP需要的内存超过了内存上限,就会引起OOM.
下面给出一个最基本的Android APP显示HelloWorld的例子.
这时如果不停的旋转屏幕, 这时通过观察Android Monitor里的Free和allocated的memory会发现 allocated 的memory会不断增加,而Free的memory会不断减小
这时通过图1中步聚5 mp java heap, 然后filter到MainActivity, 会发现MainActivity有多个实例
接着再通过MAT来分析, 图4所示
发现有很多FinalizerReference, 应该是与GC有关,由于旋转屏幕会导致MainActivity销毁并重新创建实例,而JVM在创建MainActivity实例时还有free的memory, 所以并没有触发GC,即原来的MainActivity的实例并没有被回收,所以多次旋转后,在free memory还有的情况下就会保存多个MainActivity的实例造成内存泄露的假象。当free memory 不够时,这时会触发GC, 会回收之前销毁的MainActivity的实例。
所以在查看OOM问题时,当allocated内存不断增大时,应该人为先触发GC(点击图1的4)。
如果allocated的内存没有下降,说明当前并没有可回收的实例占据内存了。
而在该例中,如果点击了initiate GC后,allocated的内存立即减少了。
Android Monitor看到MainActivity也就只有一个实例了。
❷ 如何使用MAT分析Android应用内存泄露
一、新建测试应用
1)新建一个Android 测试应用。
填写好应用的名称,以及保存位置后,直接下一步到最后点击“Finish”。
2)添加一个测试Activity:Activity2。
3)添加测试代码ActivityHelper:
这里用常用的线程长时间执行,导致外部Activity Destroy时还持有 activity的内容导致内存泄露。
主要代码如下:
public class ActivityHelper {
private Context mContext;
public ActivityHelper(Context context) {
this.mContext=context;
}
/** * 打印ActivityName */
public void printActivityName() {
for(int i = 0; i < 100; i++) {
new Thread(new Runnable() {
@Override
public void run() {
while (true)
try {
Thread.sleep(1000*30);
Log.d(ActivityHelper.class.getSimpleName(), ((Activity)mContext).getClass().getSimpleName());
} catch(InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}}
4)在Activity2中的onCreate方法中调用单例:
new ActivityHelper().printActivityName();
然后再MainActivity中点击“Setting”菜单栏打开Activity2:
Intent intent=newIntent(MainActivity.this,Activity2.class);startActivity(intent);
最后按返回键返回。
按照以上操作,运行程序。
5)多次进入Activity2之后会发现内存一直在增长,并没有降低。
而且log里会不停的输出log,打印当前activity的name
END
二、抓取内存信息
1)点击Android Studio工具栏上得“AndroidDevice Monitor”,打开后如图:
2)先在android设备上打开我们的应用
然后在devices里选中我们测试的应用,点击“update heap”
3)来回点击“settings”进入Activity2数次后,点击“DUMP HPROF file”保存文件。
4)转换HPROF文件。
利用android sdk 的工具进行转换:
到sdk/platform-tools/目录下,打开终端输入:
./hprof-conv/Users/xxx/Desktop/gc/com.lulee007.androidmemoryleakdemo.hprof/Users/xxx/Desktop/gc/com.lulee007.androidmemoryleakdemo.out.hprof
进行转换.
最终得到这个文件:com.lulee007.androidmemoryleakdemo.out.hprof
三、使用Memory Analyzer 分析
1)下载Memory Analyzer 工具:到官网下载合适的版本。
2)打开软件:从工具栏打开phrof文件选择“File”>>"openheap mp"
3)点击下面的“Action”里的“Histogram”,然后搜索ActivityHelper,得到如下结果
右击其中的一个,选择“Merge Shortest Paths to GC Roots ”>>"excludeall phantom/weak/soft etc references.."
4)可以看到,ActivityHelper本应该被释放,但是因为thead持有其中的mContext,而context是activity2里的,所有造成了内存泄露。
解决方法:
1)合理用thread,当activity2,destroy时,需要及时的停止掉thread。
2)可以设置activityhelper的while(true)改为设置变量,如while(notshutdown),
3)然后再destory里调用activityhelper,设置其notshutdown为false即可。
❸ 如何用MAT分析Android应用内存泄露
Android应用开发过程中,稍一不小心经常会出现内存泄露,如何用工具来检测下我们的应用是否存在内存泄露呢?MAT就是一款非常好用的分析应用内存使用情况的工具,使用起来也非常简单,下面小编就来和大家分享下具体的操作步骤。
工具/原料
Eclispe
MAT
方法/步骤
在Eclipse中新建一个Android工程,名字叫做:memoryleak。功能很简单,只有一个MainActivity和一个ImageUtil。我们在MainActivity中使用ImageUtil来加载图片。注意我们的ImageUtil是单例类。在创建的时候需要传入context。
应用起来以后,转屏。转屏以后,MainActivity会重建,导致ImageUtil重新加载图片。很不幸的是,因为ImageUtil并没有重建,还持有之前的Context,也就是之前的那个MainActivity实例。多次转屏以后,我们在Eclipse的DDMS里面,导出内存映像文件。导出的文件叫做:com.example.memoryleak.hprof。
DDMS导出的内存映像文件并不能被MAT直接使用。需要转换一下。在命令行输入:hprof-conv
com.example.memoryleak.hprof
memoryleak.hprof。
用MAT打开memoryleak.hprof。
点击“Histogram”
在Class
Name后面的输入框输入应用的名字:com.example.memoryleak。
可以看到有4个MainActivity实例,如果没有泄露的情况下只应该有一个实例,说明存在内存泄露。在MainActivity上点击右键->"Merge
Shortest
Paths
To
GC
Roots"->"exclude
all
phantom/weak/soft
etc.refrences"。
在打开的页面中,点击可以看到详细的引用信息。
❹ 如何使用MAT分析Android应用内存泄露
使用Android Studio,Android Device Monitor 配合Eclipse的MAT(
Memory Analyzer)工具来分析android内存泄露。
新建一个Android 测试应用。填写好应用的名称,以及保存位置后,直接下一步到最后点击“Finish”。
2、添加一个测试Activity:Activity2。
3、
添加测试代码ActivityHelper:
这里用常用的线程长时间执行,导致外部Activity Destroy时还持有 activity的内容导致内存泄露。
主要代码如下:
public class ActivityHelper {
private Context mContext;
public ActivityHelper(Context context) {
this.mContext=context;
}
/** * 打印ActivityName */
public void printActivityName() {
for (int i = 0; i < 100; i++) {
new Thread(new Runnable() {
@Override
public void run() {
while (true)
4、在Activity2中的onCreate方法中调用单例:
new ActivityHelper().printActivityName();
然后再MainActivity中点击“Setting”菜单栏打开Activity2:
Intent intent=new Intent(MainActivity.this,Activity2.class);startActivity(intent);
最后按返回键返回。
按照以上操作,运行程序。
5、
多次进入Activity2之后会发现内存一直在增长,并没有降低。
而且log里会不停的输出log,打印当前activity的name
抓取内存信息
1、点击Android Studio工具栏上得“Android Device Monitor”,打开后如图:
2、
先在android设备上打开我们的应用
然后在devices里选中我们测试的应用,点击“update heap”
3、
来回点击“settings”进入Activity2数次后,点击
“DUMP HPROF file”保存文件。
4、转换HPROF文件。
利用android sdk 的工具进行转换:
到sdk/platform-tools/目录下,打开终端输入:
./hprof-conv /Users/xxx/Desktop/gc/com.lulee007.androidmemoryleakdemo.hprof /Users/xxx/Desktop/gc/com.lulee007.androidmemoryleakdemo.out.hprof
进行转换.
最终得到这个文件:com.lulee007.androidmemoryleakdemo.out.hprof
❺ 如何使用MAT分析Android应用内存泄露
工具:MAT,Eclispe。
在Eclipse中新建一个Android工程,名字叫做:memoryleak。功能很简单,只有一个MainActivity和一个ImageUtil。我们在MainActivity中使用ImageUtil来加载图片。注意我们的ImageUtil是单例类。在创建的时候需要传入context。
2.应用起来以后,转屏。转屏以后,MainActivity会重建,导致ImageUtil重新加载图片。很不幸的是,因为ImageUtil并没有重建,还持有之前的Context,也就是之前的那个MainActivity实例。多次转屏以后,我们在Eclipse的DDMS里面,导出内存映像文件。导出的文件叫做:com.example.memoryleak.hprof。
3.DDMS导出的内存映像文件并不能被MAT直接使用。需要转换一下。在命令行输入:hprof-conv com.example.memoryleak.hprof memoryleak.hprof。
4.用MAT打开memoryleak.hprof。再点击“Histogram”,
5.在打开的页面中,点击可以看到详细的引用信息,就可以看没有出错了。
❻ android mat 什么意思
MAT(Memory Analyzer Tool),一个内存分析工具,是一个快速、功能丰富的JAVA heap分析工具,它可以帮助我们查找内存泄漏和减少内存消耗。使用内存分析工具从众多的对象中进行分析,快速的计算出在内存中对象的占用大小,看看是谁阻止了垃圾收集器的回收工作,并可以通过报表直观的查看到可能造成这种结果的对象。
你可以把它集成到android studio或者Eclipse里面。然后使用它分析你的app。具体的使用方法你可以网上搜索。
❼ 如何使用MAT分析Android应用内存泄露
举个例子,方法步骤见下:
1在Eclipse中新建一个Android工程,名字叫做:memoryleak。功能很简单,只有一个MainActivity和一个ImageUtil。在MainActivity中使用ImageUtil来加载图片。注意ImageUtil是单例类。在创建的时候需要传入context。
2应用起来以后,转屏。转屏以后,MainActivity会重建,导致ImageUtil重新加载图片。很不幸的是,因为ImageUtil并没有重建,还持有之前的Context,也就是之前的那个MainActivity实例。多次转屏以后,在Eclipse的DDMS里面,导出内存映像文件。导出的文件叫做:com.example.memoryleak.hprof。
3DDMS导出的内存映像文件并不能被MAT直接使用。需要转换一下。在命令行输入:hprof-conv com.example.memoryleak.hprof memoryleak.hprof。
4用MAT打开memoryleak.hprof。
5点击“Histogram”
6在Class Name后面的输入框输入应用的名字:com.example.memoryleak。
7可以看到有4个MainActivity实例,如果没有泄露的情况下只应该有一个实例,说明存在内存泄露。在MainActivity上点击右键->"Merge Shortest Paths To GC Roots"->"exclude all phantom/weak/soft etc.refrences"。
8在打开的页面中,点击可以看到详细的引用信息。
9上图中可以看出来是ImageUtil引用了一个MainActivity的实例。这样就找到了泄露的根源,就可以进行处理了。
❽ 如何使用MAT分析Android应用内存泄露
1、新建测试应用
1
新建一个Android 测试应用。
填写好应用的名称,以及保存位置后,直接下一步到最后点击“Finish”。
2
添加一个测试Activity:Activity2。
3
添加测试代码ActivityHelper:
这里用常用的线程长时间执行,导致外部Activity Destroy时还持有 activity的内容导致内存泄露。
主要代码如下:
public class ActivityHelper {
private Context mContext;
public ActivityHelper(Context context) {
this.mContext=context;
}
/** * 打印ActivityName */
public void printActivityName() {
for (int i = 0; i < 100; i++) {
new Thread(new Runnable() {
@Override
public void run() {
while (true)
try {
Thread.sleep(1000*30);
Log.d(ActivityHelper.class.getSimpleName(), ((Activity) mContext).getClass().getSimpleName());
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}).start();
}
}}
4
在Activity2中的onCreate方法中调用单例:
new ActivityHelper().printActivityName();
然后再MainActivity中点击“Setting”菜单栏打开Activity2:
Intent intent=new Intent(MainActivity.this,Activity2.class);startActivity(intent);
最后按返回键返回。
按照以上操作,运行程序。
5
多次进入Activity2之后会发现内存一直在增长,并没有降低。
而且log里会不停的输出log,打印当前activity的name
2、抓取内存信息
1
点击Android Studio工具栏上得“Android Device Monitor”,打开后如图:
2
先在android设备上打开我们的应用
然后在devices里选中我们测试的应用,点击“update heap”
3
来回点击“settings”进入Activity2数次后,点击
“DUMP HPROF file”保存文件。
4
转换HPROF文件。
利用android sdk 的工具进行转换:
到sdk/platform-tools/目录下,打开终端输入:
./hprof-conv /Users/xxx/Desktop/gc/com.lulee007.androidmemoryleakdemo.hprof /Users/xxx/Desktop/gc/com.lulee007.androidmemoryleakdemo.out.hprof
进行转换.
最终得到这个文件:com.lulee007.androidmemoryleakdemo.out.hprof
3、使用Memory Analyzer 分析
下载Memory Analyzer 工具:
到官网下载:
http://www.eclipse.org/mat/downloads.php
选择合适的版本。
打开软件:
从工具栏打开phrof文件选择“File”>>"open heap mp"
点击下面的“Action”里的“Histogram”,然后搜索ActivityHelper
得到如下结果
右击其中的一个,选择“Merge Shortest Paths to GC Roots ”>>"exclude all phantom/weak/soft etc references.."
可以看到,ActivityHelper本应该被释放,但是因为thead持有其中的mContext,而context是activity2里的,所有造成了内存泄露。
解决方法:
合理用thread,当activity2,destroy时,需要及时的停止掉thread。
可以设置activityhelper的while(true)改为设置变量,如while(notshutdown),
然后再destory里调用activityhelper,设置其notshutdown为false即可。