LeakCanary: Detect all memory leaks!
2016-01-21 15:19
375 查看
转载:https://corner.squareup.com/2015/05/leak-canary.html
of out of memory (OOM) crashes when creating it.
We tried a few approaches, none of which solved the issue:
Use
Catch
(inspired from GCUtils).
We didn’t think of allocating bitmaps off the Java heap. Lucky for us, Fresco didn’t exist yet.
leaks.
the app runs out of memory.
For instance, after
the activity, its view hierarchy and their associated bitmaps should all be garbage collectable. If a thread running in the background holds a reference to the activity, then the corresponding memory cannot be reclaimed. This eventually leads to an
Here are the key steps:
Learn about
or the Developer Console.
Attempt to reproduce the problem. You might need to buy, borrow, or steal the specific device that suffered the crash. (Not all devices will exhibit all leaks!) You also need to figure out what navigation sequence triggers the leak, possibly by brute force.
Dump the heap when the OOM occurs (here’s how).
Poke around the heap dump with MAT or YourKit and find an object that should have been garbage collected.
Compute the shortest strong reference path from that object to the GC roots.
Figure out which reference in the path should not exist, and fix the memory leak.
What if a library could do all this before you even get to an OOM, and let you focus on fixing the memory leak?
Let’s look at a cat example:
You create a
an object to watch:
When the leak is detected, you automatically get a nice leak trace:
We know you’re busy writing features, so we made it very easy to setup. With just one line of code, LeakCanary will automatically detect activity leaks:
You get a notification and a nice display out of the box:
in the Android SDK.
The results are amazing. We now have 94% fewer crashes from OOM errors.
If you want to eliminate OOM crashes, install LeakCanary now!
java.lang.OutOfMemoryError at android.graphics.Bitmap.nativeCreate(Bitmap.java:-2) at android.graphics.Bitmap.createBitmap(Bitmap.java:689) at com.squareup.ui.SignView.createSignatureBitmap(SignView.java:121)
Nobody likes OutOfMemoryError crashes
In Square Register, we draw the customer’s signature on a bitmap cache. This bitmap is the size of the device’s screen, and we had a significant numberof out of memory (OOM) crashes when creating it.
We tried a few approaches, none of which solved the issue:
Use
Bitmap.Config.ALPHA_8(a signature doesn’t need color).
Catch
OutOfMemoryError, trigger the GC and retry a few times
(inspired from GCUtils).
We didn’t think of allocating bitmaps off the Java heap. Lucky for us, Fresco didn’t exist yet.
We were looking at it the wrong way
The bitmap size was not a problem. When the memory is almost full, an OOM can happen anywhere. It tends to happen more often in places where you create big objects, like bitmaps. The OOM is a symptom of a deeper problem: memoryleaks.
What is a memory leak?
Some objects have a limited lifetime. When their job is done, they are expected to be garbage collected. If a chain of references holds an object in memory after the end of its expected lifetime, this creates a memory leak. When these leaks accumulate,the app runs out of memory.
For instance, after
Activity.onDestroy()is called,
the activity, its view hierarchy and their associated bitmaps should all be garbage collectable. If a thread running in the background holds a reference to the activity, then the corresponding memory cannot be reclaimed. This eventually leads to an
OutOfMemoryErrorcrash.
Hunting memory leaks
Hunting memory leaks is a manual process, well described in Raizlabs’ Wrangling Dalvik series.Here are the key steps:
Learn about
OutOfMemoryErrorcrashes via Bugsnag, Crashlytics,
or the Developer Console.
Attempt to reproduce the problem. You might need to buy, borrow, or steal the specific device that suffered the crash. (Not all devices will exhibit all leaks!) You also need to figure out what navigation sequence triggers the leak, possibly by brute force.
Dump the heap when the OOM occurs (here’s how).
Poke around the heap dump with MAT or YourKit and find an object that should have been garbage collected.
Compute the shortest strong reference path from that object to the GC roots.
Figure out which reference in the path should not exist, and fix the memory leak.
What if a library could do all this before you even get to an OOM, and let you focus on fixing the memory leak?
Introducing LeakCanary
LeakCanary is an Open Source Java library to detect memory leaks in your debug builds.Let’s look at a cat example:
class Cat { } class Box { Cat hiddenCat; } class Docker { static Box container; } // ... Box box = new Box(); Cat schrodingerCat = new Cat(); box.hiddenCat = schrodingerCat; Docker.container = box;
You create a
RefWatcherinstance and give it
an object to watch:
// We expect schrodingerCat to be gone soon (or not), let's watch it. refWatcher.watch(schrodingerCat);
When the leak is detected, you automatically get a nice leak trace:
* GC ROOT static Docker.container * references Box.hiddenCat * leaks Cat instance
We know you’re busy writing features, so we made it very easy to setup. With just one line of code, LeakCanary will automatically detect activity leaks:
public class ExampleApplication extends Application { @Override public void onCreate() { super.onCreate(); LeakCanary.install(this); } }
You get a notification and a nice display out of the box:
Conclusion
After enabling LeakCanary, we discovered and fixed many memory leaks in our app. We even found a few leaksin the Android SDK.
The results are amazing. We now have 94% fewer crashes from OOM errors.
If you want to eliminate OOM crashes, install LeakCanary now!
相关文章推荐
- 在Vim里使用gtags-cscope
- 如何维护好服务器的安全
- 超级无敌qmail安装大法,详尽之极
- C++中声明类的class与声明结构体的struct关键字详解
- 为 Drupal 7 网站添加自定义CSS
- php整合memcached
- leetcode之power of three
- 两个项目跳转,session丢失
- [精华] qmail安装心得(安装过程)
- VS2010编辑界面主题美化
- iOS开发---给图片加水印
- 2416开发记录十:platform的相关函数详解
- Java中配置文件Properties类的简单操作
- 迟来的2015年终总结
- Leetcode--Permutation Sequence
- JS遍历Table合并单元格
- 详解java定时任务
- 什么才算是真正的编程能力
- Python脚本email
- zabbix监控nginx连接状态