当前位置: 首页 > 科技观察

LeakCanary:检测所有内存泄漏

时间:2023-03-18 21:17:48 科技观察

原文:LeakCanary:检测所有内存泄漏!ava.lang.OutOfMemoryErroratandroid.graphics.Bitmap.nativeCreate(Bitmap.java:-2)atandroid.graphics.Bitmap.createBitmap(Bitmap.java:689)atcom.squareup.ui.SignView.createSignatureBitmap(SignView.java:121)没有人喜欢OutOfMemoryError在Square的注册过程中,我们在位图上画了一个用户的签名。位图是设备屏幕的大小,在创建它时,我遇到了相当多的OOM导致的崩溃。我们尝试了几种方法,但都没有解决我们的问题:使用Bitmap.Config.ALPHA_8(签名无色)捕获OutOfMemoryError,触发垃圾收集并重试几次(灵感来自GCUtils)我们没有考虑将位图分配到heapmemory,而那个时候Fresco还没有出现。我们看问题的方式是错误的。位图本身的大小不是问题。当内存快满时,随时随地都可能发生OOM。尤其是在创建大型对象(例如位图)时。OOM一般代表更深层次的问题:内存泄漏。什么是内存泄漏?有些对象只有有限的生命周期。当他们的任务完成时,他们将被垃圾收集。如果在对象的生命周期应该结束时对象仍然被一系列引用引用,这将导致内存泄漏。随着泄漏的累积,应用程序将耗尽内存。例如,在调用Activity.onDestroy()之后,视图树和关联的位图应该被垃圾回收。如果一个正在运行的后台线程继续持有这个Activity的引用,关联的内存将不会被回收,最终会导致OutOfMemoryError崩溃。查找内存泄漏查找内存泄漏是一个手动过程,在Raizlabs的WranglingDalvik系列中有详细描述。以下是关键步骤:通过Bugsnag、Crashlytics或DeveloperConsole了解OOM主动重现问题。您可能需要购买、借用或窃取发生崩溃的特殊设备(并非所有设备都有内存泄漏!)。您还需要找出导致内存泄漏的原因。当OOM发生时转储堆(这里是如何做的)。使用MAT或YourKit内存检测工具来检测内存变化,找出哪些对象应该被垃圾回收;从该对象外推到GCroots强引用的最短路径;在路径中找到不存在的引用,并修复内存泄漏;如果有一个库可以为您完成所有工作,让您专注于修复内存泄漏,那该有多好。LeakCanary简介LeakCanary是一个用于在调试版本中检测内存泄漏的开源Java库。我们来看一个cait的例子:创建一个RefWatcher实例,然后给它一个对象让它观看://WeexpectschrodingerCattobegonesoon(ornot),let'swatchit.refWatcher.watch(schrodingerCat);当检测到泄漏时,您会自动获得一个很好的泄漏线索:*GCROOTstaticDocker.container*referencesBox.hiddenCat*leaksCatinstance我们知道您的时间很宝贵,所以我们让它变得非常容易设置。LeakCanary只需几行代码就可以自动检测Activity泄漏:publicclassExampleApplicationextendsApplication{@OverridepublicvoidonCreate(){super.onCreate();LeakCanary.install(this);}}当内存不足时,会有通知和漂亮的显示接口:结论启用LeakCanary后,我们发现并修复了许多内存泄漏。我们甚至在AndroidSDK中发现了一些漏洞。结果非常惊人,我们现在将oom崩溃减少了94%。如果您想结束OOM崩溃,请立即安装LeakCanary!