amcap win7官方下载-仙4下载

内存检测
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:

*.(named'AsyncTask#1')

*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"?>

MyLeaks

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"?>

20

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

更多推荐

内存检测