amcap win7官方下载-仙4下载
![内存检测](/uploads/image/0411.jpg)
2023年4月6日发(作者:flv播放器)
内存泄露检测⼯具—LeakCanary
很简单:我们不是创建服务不是为了赚钱;我们赚钱是为了提供更好的服务。我们认为这才是做事的态度。
学习使⽤Java的同学都应该知道,Java的JVM给我们提供的垃圾回收机制是极为好⽤的。但是我们也很清楚,垃圾回收机制不是万能的,使⽤不当很
容易造成内存泄露。之前我们也介绍过Java中常⽤的内存泄露检测⼯具MAT,⽬前Java程序最常⽤的内存分析⼯具应该是MAT(MemoryAnalyzer
Tool),它是⼀个Eclipse插件,同时也有单独的RCP客户端。
今天,这⾥我们不说MAT,我们说⼀个更有⽤的开源⼯具——LeakCanary。
LeakCanary本质上就是⼀个基于MAT进⾏Android应⽤程序内存泄漏⾃动化检测的的开源⼯具,通过集成这个⼯具代码到⾃⼰的Android⼯程当中就
能够在程序调试开发过程中通过⼀个漂亮的界⾯。
随时发现和定位内存泄漏问题,⽽不⽤每次在开发流程中都抽出专⼈来进⾏内存泄漏问题检测,极⼤地⽅便了Android应⽤程序的开发。
总的来说,LeakCanary有如下⼏个明显优点:
1.针对AndroidActivity组件完全⾃动化的内存泄漏检查。
2.可定制⼀些⾏为(dump⽂件和leaktrace对象的数量、⾃定义例外、分析结果的⾃定义处理等)。
3.集成到⾃⼰⼯程并使⽤的成本很低。(*主要)
4.友好的界⾯展⽰和通知。
具体怎么使⽤?应⽤⼀下官⽅的翻译⽂档⼊下:
LeakCanary
Android和Java内存泄露检测。
“Asmallleakwillsinkagreatship.”-BenjaminFranklin
千⾥之堤,毁于蚁⽳。–《韩⾮⼦·喻⽼》
开始使⽤
在中加⼊引⽤,不同的编译使⽤不同的引⽤:
dependencies{
debugCompile'nary:leakcanary-android:1.3'
releaseCompile'nary:leakcanary-android-no-op:1.3'
}
1
2
3
4
在Application中:
publicclassExampleApplicationextendsApplication{
@OverridepublicvoidonCreate(){
te();
l(this);
}
1
2
3
4
5
6
这样,就万事俱备了!在debugbuild中,如果检测到某个activity有内存泄露,LeakCanary就是⾃动地显⽰⼀个通知。
如何使⽤
使⽤RefWatcher监控那些本该被回收的对象。
RefWatcherrefWatcher={...};
//监控
//监控
(schrodingerCat);
1
2
3
4
l()会返回⼀个预定义的RefWatcher,同时也会启⽤⼀个ActivityRefWatcher,⽤于⾃动监控调⽤roy()之后泄露的
activity。
publicclassExampleApplicationextendsApplication{
publicstaticRefWatchergetRefWatcher(Contextcontext){
ExampleApplicationapplication=(ExampleApplication)licationContext();
cher;
}
privateRefWatcherrefWatcher;
@OverridepublicvoidonCreate(){
te();
refWatcher=l(this);
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
使⽤RefWatcher监控Fragment:
publicabstractclassBaseFragmentextendsFragment{
@Override
publicvoidonDestroy(){
roy();
RefWatcherrefWatcher=Watcher(getActivity());
(this);
}
}
1
2
3
4
5
6
7
8
9
⼯作机制
()创建⼀个KeyedWeakReference到要被监控的对象。
2.然后在后台线程检查引⽤是否被清除,如果没有,调⽤GC。
3.如果引⽤还是未被清除,把heap内存dump到APP对应的⽂件系统中的⼀个.hprof⽂件中。
4.在另外⼀个进程中的HeapAnalyzerService有⼀个HeapAnalyzer使⽤HAHA解析这个⽂件。
5.得益于唯⼀的referencekey,HeapAnalyzer找到KeyedWeakReference,定位内存泄露。
alyzer计算到GCroots的最短强引⽤路径,并确定是否是泄露。如果是的话,建⽴导致泄露的引⽤链。
7.引⽤链传递到APP进程中的DisplayLeakService,并以通知的形式展⽰出来。
如何复制leaktrace?
在Logcat中,你可以看到类似这样的leaktrace:
nary:1.0:tivityhasleaked:
*.
*tivity$$0(ask)
*tivityinstance
*ReferenceKey:e71f3bf5-d786-4145-8539-584afaecad1d
*Device:GenymotiongenericGoogleNexus6-5.1.0-API22-1440x2560vbox86p
*AndroidVersion:5.1API:22
*Durations:watch=5086ms,gc=110ms,heapdump=435ms,analysis=2086ms
1
2
3
4
5
6
7
8
9
10
11
你甚⾄可以通过分享按钮把这些东西分享出去。
SDK导致的内存泄露
随着时间的推移,很多SDK和⼚商ROM中的内存泄露问题已经被尽快修复了。但是,当这样的问题发⽣时,⼀般的开发者能做的事情很有限。
LeakCanary有⼀个已知问题的忽略列表,,如果你发现了⼀个新的问题,请提⼀个issue并附上leaktrace,reference
key,机器型号和SDK版本。如果可以附带上dump⽂件的链接那就再好不过了。
对于最新发布的Android,这点尤其重要。你有机会在帮助在早期发现新的内存泄露,这对整个Android社区都有极⼤的益处。
leaktrace之外
有时,leaktrace不够,你需要通过MAT或者YourKit深挖dump⽂件。
通过以下⽅法,你能找到问题所在:
1.查找所有的eakReference实例。
2.检查key字段
eKeyedWeakReferencethathasakeyfieldequaltothereferencekeyreportedbyLeakCanary.
4.找到key和和logcat输出的key值⼀样的KeyedWeakReference。
nt字段对应的就是泄露的对象。
6.剩下的,就是动⼿修复了。最好是检查到GCroot的最短强引⽤路径开始。
⾃定义
UI样式
DisplayLeakActivity有⼀个默认的图标和标签,你只要在你⾃⼰的APP资源中,替换以下资源就可。
res/
drawable-hdpi/
__leak_canary_
drawable-mdpi/
__leak_canary_
drawable-xhdpi/
__leak_canary_
drawable-xxhdpi/
__leak_canary_
drawable-xxxhdpi/
__leak_canary_
<?xmlversion="1.0"encoding="utf-8"?>
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
保存leaktrace
DisplayLeakActivitysavesupto7heapdumps&r.__leak_canary_max_stored_leaksinyourapp:
1
在APP的⽬录中,DisplayLeakActivity保存了7个dump⽂件和leaktrace。你可以在你的APP中,定义
r.__leak_canary_max_stored_leaks来覆盖类库的默认值。
<?xmlversion="1.0"encoding="utf-8"?>
1
2
3
4
上传leaktrace到服务器
你可以改变处理完成的默认⾏为,将leaktrace和heapdump上传到你的服务器以便统计分析。
创建⼀个LeakUploadService,最简单的就是继承DisplayLeakService:
publicclassLeakUploadServiceextendsDisplayLeakService{
@Override
protectedvoidafterDefaultHandling(HeapDumpheapDump,AnalysisResultresult,StringleakInfo){
if(!und||edLeak){
return;
}
LeakBlocking(mpFile,leakInfo);
}
}
1
2
3
4
5
6
7
8
9
请确认release版本使⽤ED:
publicclassExampleApplicationextendsApplication{
publicstaticRefWatchergetRefWatcher(Contextcontext){
ExampleApplicationapplication=(ExampleApplication)licationContext();
cher;
}
privateRefWatcherrefWatcher;
@OverridepublicvoidonCreate(){
te();
refWatcher=installLeakCanary();
}
}
protectedRefWatcherinstallLeakCanary(){
ED;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
⾃定义RefWatcher:
publicclassDebugExampleApplicationextendsExampleApplication{
protectedRefWatcherinstallLeakCanary(){
l(app,);
}
}
1
2
3
4
5
别忘了注册service:
<?xmlversion="1.0"encoding="utf-8"?>
xmlns:android="/apk/res/android"
xmlns:tools="/tools"
>
1
2
3
4
5
6
7
8
9
demo
更多推荐
内存检测
发布评论