![Page 1: Leak Canary Intro Jennifer McGee - Meetupfiles.meetup.com/1791179/LeakCanaryIntro.pdfwrite external permissions, but on 6.0 this must be requested at run time Fix: use 1.4-beta1 or](https://reader035.vdocuments.site/reader035/viewer/2022070801/5f02abd47e708231d4056d7d/html5/thumbnails/1.jpg)
1
Leak Canary Intro
Jennifer McGee
![Page 2: Leak Canary Intro Jennifer McGee - Meetupfiles.meetup.com/1791179/LeakCanaryIntro.pdfwrite external permissions, but on 6.0 this must be requested at run time Fix: use 1.4-beta1 or](https://reader035.vdocuments.site/reader035/viewer/2022070801/5f02abd47e708231d4056d7d/html5/thumbnails/2.jpg)
What is Leak Canary?
Leak Canary
•Open source library written by Square’s
Pierre-Yves (PY) Ricau
•Library which attempts to automatically
detect and report memory leaks in android
![Page 3: Leak Canary Intro Jennifer McGee - Meetupfiles.meetup.com/1791179/LeakCanaryIntro.pdfwrite external permissions, but on 6.0 this must be requested at run time Fix: use 1.4-beta1 or](https://reader035.vdocuments.site/reader035/viewer/2022070801/5f02abd47e708231d4056d7d/html5/thumbnails/3.jpg)
Leak Cannary
Memory Leaks in Java
3
![Page 4: Leak Canary Intro Jennifer McGee - Meetupfiles.meetup.com/1791179/LeakCanaryIntro.pdfwrite external permissions, but on 6.0 this must be requested at run time Fix: use 1.4-beta1 or](https://reader035.vdocuments.site/reader035/viewer/2022070801/5f02abd47e708231d4056d7d/html5/thumbnails/4.jpg)
Objects Reachable
from GC Roots
GC Roots
GC Overview
4
GC Root GC Root
Object
ObjectObject
Object
ObjectObject
![Page 5: Leak Canary Intro Jennifer McGee - Meetupfiles.meetup.com/1791179/LeakCanaryIntro.pdfwrite external permissions, but on 6.0 this must be requested at run time Fix: use 1.4-beta1 or](https://reader035.vdocuments.site/reader035/viewer/2022070801/5f02abd47e708231d4056d7d/html5/thumbnails/5.jpg)
Not Reachable from GC Root
GC Roots
GC Overview
5
GC Root GC Root
Object
ObjectObject
Object
ObjectObject
Can be garbage collected
![Page 6: Leak Canary Intro Jennifer McGee - Meetupfiles.meetup.com/1791179/LeakCanaryIntro.pdfwrite external permissions, but on 6.0 this must be requested at run time Fix: use 1.4-beta1 or](https://reader035.vdocuments.site/reader035/viewer/2022070801/5f02abd47e708231d4056d7d/html5/thumbnails/6.jpg)
Leak Cannary
How Leak Canary Works
6
![Page 7: Leak Canary Intro Jennifer McGee - Meetupfiles.meetup.com/1791179/LeakCanaryIntro.pdfwrite external permissions, but on 6.0 this must be requested at run time Fix: use 1.4-beta1 or](https://reader035.vdocuments.site/reader035/viewer/2022070801/5f02abd47e708231d4056d7d/html5/thumbnails/7.jpg)
Basic Idea
1) Identify objects you are worried about leaking 2) When they are destroyed keep a week reference 3) Wait 4) If not garbage collected notify of possible memory leak
Android Memory Leaks
7
![Page 8: Leak Canary Intro Jennifer McGee - Meetupfiles.meetup.com/1791179/LeakCanaryIntro.pdfwrite external permissions, but on 6.0 this must be requested at run time Fix: use 1.4-beta1 or](https://reader035.vdocuments.site/reader035/viewer/2022070801/5f02abd47e708231d4056d7d/html5/thumbnails/8.jpg)
Key Classes
Leak Canary
8
![Page 9: Leak Canary Intro Jennifer McGee - Meetupfiles.meetup.com/1791179/LeakCanaryIntro.pdfwrite external permissions, but on 6.0 this must be requested at run time Fix: use 1.4-beta1 or](https://reader035.vdocuments.site/reader035/viewer/2022070801/5f02abd47e708231d4056d7d/html5/thumbnails/9.jpg)
What does RefWatcher Coordinate Leak Canary
9
![Page 10: Leak Canary Intro Jennifer McGee - Meetupfiles.meetup.com/1791179/LeakCanaryIntro.pdfwrite external permissions, but on 6.0 this must be requested at run time Fix: use 1.4-beta1 or](https://reader035.vdocuments.site/reader035/viewer/2022070801/5f02abd47e708231d4056d7d/html5/thumbnails/10.jpg)
How Do We Guess when activities Should have been garbage collected?
Android Memory Leaks
10
![Page 11: Leak Canary Intro Jennifer McGee - Meetupfiles.meetup.com/1791179/LeakCanaryIntro.pdfwrite external permissions, but on 6.0 this must be requested at run time Fix: use 1.4-beta1 or](https://reader035.vdocuments.site/reader035/viewer/2022070801/5f02abd47e708231d4056d7d/html5/thumbnails/11.jpg)
RecyclerView
11
Q: How can we guess when fragments should have been garbage collected?
A: Extend Fragment
public abstract class BaseFragment extends Fragment {
@Override public void onDestroy() {
super.onDestroy();
RefWatcher refWatcher = ExampleApplication.getRefWatcher(getActivity());
refWatcher.watch(this);
}
}
![Page 12: Leak Canary Intro Jennifer McGee - Meetupfiles.meetup.com/1791179/LeakCanaryIntro.pdfwrite external permissions, but on 6.0 this must be requested at run time Fix: use 1.4-beta1 or](https://reader035.vdocuments.site/reader035/viewer/2022070801/5f02abd47e708231d4056d7d/html5/thumbnails/12.jpg)
Leak Cannary
Leak Canary Leak Demo
12
![Page 13: Leak Canary Intro Jennifer McGee - Meetupfiles.meetup.com/1791179/LeakCanaryIntro.pdfwrite external permissions, but on 6.0 this must be requested at run time Fix: use 1.4-beta1 or](https://reader035.vdocuments.site/reader035/viewer/2022070801/5f02abd47e708231d4056d7d/html5/thumbnails/13.jpg)
Leak Cannary
13
public class MainActivity extends Activity { @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main_activity); View button = findViewById(R.id.async_task); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { startAsyncTask(); } }); } void startAsyncTask() { // This async task is an anonymous class and therefore has a hidden reference to the outer // class MainActivity. If the activity gets destroyed before the task finishes (e.g. rotation), // the activity instance will leak. new AsyncTask<Void, Void, Void>() { @Override protected Void doInBackground(Void... params) { // Do some slow work in background SystemClock.sleep(20000); return null; } }.execute(); }}
Activity that Will Leak
![Page 14: Leak Canary Intro Jennifer McGee - Meetupfiles.meetup.com/1791179/LeakCanaryIntro.pdfwrite external permissions, but on 6.0 this must be requested at run time Fix: use 1.4-beta1 or](https://reader035.vdocuments.site/reader035/viewer/2022070801/5f02abd47e708231d4056d7d/html5/thumbnails/14.jpg)
Leak Cannary
14
02-21 17:52:58.124 31708-13109/com.example.leakcanary D/LeakCanary: In com.example.leakcanary:1.0:1.
02-21 17:52:58.124 31708-13109/com.example.leakcanary D/LeakCanary: * com.example.leakcanary.MainActivity has leaked:
02-21 17:52:58.124 31708-13109/com.example.leakcanary D/LeakCanary: * GC ROOT thread java.lang.Thread.<Java Local> (named 'AsyncTask #2’)
02-21 17:52:58.124 31708-13109/com.example.leakcanary D/LeakCanary: * references com.example.leakcanary.MainActivity$2.this$0 (anonymous subclass of android.os.AsyncTask)
02-21 17:52:58.124 31708-13109/com.example.leakcanary D/LeakCanary: * leaks com.example.leakcanary.MainActivity instance
02-21 17:52:58.124 31708-13109/com.example.leakcanary D/LeakCanary: * Retaining: 260KB.
02-21 17:52:58.124 31708-13109/com.example.leakcanary D/LeakCanary: * Reference Key: f856c32b-53ad-4f31-bb5b-a51c2208943c
02-21 17:52:58.124 31708-13109/com.example.leakcanary D/LeakCanary: * Device: Genymotion generic Samsung Galaxy S4 - 4.4.4 - API 19 - 1080x1920 vbox86p
02-21 17:52:58.124 31708-13109/com.example.leakcanary D/LeakCanary: * Android Version: 4.4.4 API: 19 LeakCanary: 1.4-SNAPSHOT
What a Leak Log Looks Like
What has Leaked
GC Root
How much Memory
Reference Key
![Page 15: Leak Canary Intro Jennifer McGee - Meetupfiles.meetup.com/1791179/LeakCanaryIntro.pdfwrite external permissions, but on 6.0 this must be requested at run time Fix: use 1.4-beta1 or](https://reader035.vdocuments.site/reader035/viewer/2022070801/5f02abd47e708231d4056d7d/html5/thumbnails/15.jpg)
Android Memory Leaks
How to Setup Leak Canary in your App
15
![Page 16: Leak Canary Intro Jennifer McGee - Meetupfiles.meetup.com/1791179/LeakCanaryIntro.pdfwrite external permissions, but on 6.0 this must be requested at run time Fix: use 1.4-beta1 or](https://reader035.vdocuments.site/reader035/viewer/2022070801/5f02abd47e708231d4056d7d/html5/thumbnails/16.jpg)
RecyclerView
16
Basic Leak Canary SetupIn your Gradle File:
dependencies {
debugCompile 'com.squareup.leakcanary:leakcanary-android:1.3.1'
releaseCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3.1'
testCompile 'com.squareup.leakcanary:leakcanary-android-no-op:1.3.1'
}
In your Application Class:
public class ExampleApplication extends Application {
@Override public void onCreate() {
super.onCreate();
LeakCanary.install(this);
}
}
![Page 17: Leak Canary Intro Jennifer McGee - Meetupfiles.meetup.com/1791179/LeakCanaryIntro.pdfwrite external permissions, but on 6.0 this must be requested at run time Fix: use 1.4-beta1 or](https://reader035.vdocuments.site/reader035/viewer/2022070801/5f02abd47e708231d4056d7d/html5/thumbnails/17.jpg)
Android Memory Leaks
What about Memory Leaks you Can’t Fix?
17
![Page 18: Leak Canary Intro Jennifer McGee - Meetupfiles.meetup.com/1791179/LeakCanaryIntro.pdfwrite external permissions, but on 6.0 this must be requested at run time Fix: use 1.4-beta1 or](https://reader035.vdocuments.site/reader035/viewer/2022070801/5f02abd47e708231d4056d7d/html5/thumbnails/18.jpg)
LeakCanary
18
What Does LeakCanary.install(this) do? Lets look at the source
public static RefWatcher install(Application application) {
return install(application, DisplayLeakService.class,
AndroidExcludedRefs.createAppDefaults().build());
}
public static RefWatcher install(Application application,
Class<? extends AbstractAnalysisResultService> listenerServiceClass,
ExcludedRefs excludedRefs) {
…
Look there it has an
overwritten constructor!
We
pass
in
Excl
uded
Ref
s O
bjec
t
![Page 19: Leak Canary Intro Jennifer McGee - Meetupfiles.meetup.com/1791179/LeakCanaryIntro.pdfwrite external permissions, but on 6.0 this must be requested at run time Fix: use 1.4-beta1 or](https://reader035.vdocuments.site/reader035/viewer/2022070801/5f02abd47e708231d4056d7d/html5/thumbnails/19.jpg)
LeakCanary
19
How To Add 3rd Party Exclusions
ExcludedRefs excludedRefs = AndroidExcludedRefs.createAppDefaults()
.instanceField("com.example.third.party.TheirClassOne", "fieldName")
.instanceField("com.example.third.party.TheirClassTwo", "fieldName")
.build();
LeakCanary.install(application, DisplayLeakService.class, excludedRefs);
Add in the additional exclusions
here
![Page 20: Leak Canary Intro Jennifer McGee - Meetupfiles.meetup.com/1791179/LeakCanaryIntro.pdfwrite external permissions, but on 6.0 this must be requested at run time Fix: use 1.4-beta1 or](https://reader035.vdocuments.site/reader035/viewer/2022070801/5f02abd47e708231d4056d7d/html5/thumbnails/20.jpg)
LeakCanary
20
Excluded Refs Builder Interface
public interface Builder { BuilderWithParams instanceField(String className, String fieldName); BuilderWithParams staticField(String className, String fieldName); BuilderWithParams thread(String threadName); BuilderWithParams clazz(String className); BuilderWithParams rootClass(String rootSuperClassName); ExcludedRefs build();}
![Page 21: Leak Canary Intro Jennifer McGee - Meetupfiles.meetup.com/1791179/LeakCanaryIntro.pdfwrite external permissions, but on 6.0 this must be requested at run time Fix: use 1.4-beta1 or](https://reader035.vdocuments.site/reader035/viewer/2022070801/5f02abd47e708231d4056d7d/html5/thumbnails/21.jpg)
LeakCanary
21
Known Android SDK Leaks are in AndroidExcludedRefs.java
Parts of an Excluded Leak:
Name (Manufacturer and SDK Range){ @Override void add(ExcludedRefs.Builder excluded) {
excluded.type of field <instance,static,root class, clazz>(“full.path.ClassToIgnore”, “field that was leaked")
.reason(“comment reason for the leak”); } } }
https://github.com/square/leakcanary/blob/master/leakcanary-android/src/main/java/com/squareup/leakcanary/AndroidExcludedRefs.java
![Page 22: Leak Canary Intro Jennifer McGee - Meetupfiles.meetup.com/1791179/LeakCanaryIntro.pdfwrite external permissions, but on 6.0 this must be requested at run time Fix: use 1.4-beta1 or](https://reader035.vdocuments.site/reader035/viewer/2022070801/5f02abd47e708231d4056d7d/html5/thumbnails/22.jpg)
Android Memory Leaks
Leak Canary Gotcha’s
22
![Page 23: Leak Canary Intro Jennifer McGee - Meetupfiles.meetup.com/1791179/LeakCanaryIntro.pdfwrite external permissions, but on 6.0 this must be requested at run time Fix: use 1.4-beta1 or](https://reader035.vdocuments.site/reader035/viewer/2022070801/5f02abd47e708231d4056d7d/html5/thumbnails/23.jpg)
Leak Cannary
23
Leak Canary on 6.0 and latter phones
![Page 24: Leak Canary Intro Jennifer McGee - Meetupfiles.meetup.com/1791179/LeakCanaryIntro.pdfwrite external permissions, but on 6.0 this must be requested at run time Fix: use 1.4-beta1 or](https://reader035.vdocuments.site/reader035/viewer/2022070801/5f02abd47e708231d4056d7d/html5/thumbnails/24.jpg)
Leak Cannary
24
Here is what you see in the Log 02-21 19:37:13.544 15173-15188/com.example.leakcanary D/LeakCanary: Could not attempt cleanup, leak storage not writable.02-21 19:37:24.592 15173-15189/com.example.leakcanary D/LeakCanary: Could not write to leak storage to dump heap.
Cause:
LeakCannary needs to write out heap dumps to external storage, so it needs the read and write external permissions, but on 6.0 this must be requested at run time
Fix:
use 1.4-beta1 or latter
enable storage permission when notification pops up notification
Leak Canary on 6.0 and latter phones
![Page 25: Leak Canary Intro Jennifer McGee - Meetupfiles.meetup.com/1791179/LeakCanaryIntro.pdfwrite external permissions, but on 6.0 this must be requested at run time Fix: use 1.4-beta1 or](https://reader035.vdocuments.site/reader035/viewer/2022070801/5f02abd47e708231d4056d7d/html5/thumbnails/25.jpg)
Android Memory Leaks
Fun with OQL
25
![Page 26: Leak Canary Intro Jennifer McGee - Meetupfiles.meetup.com/1791179/LeakCanaryIntro.pdfwrite external permissions, but on 6.0 this must be requested at run time Fix: use 1.4-beta1 or](https://reader035.vdocuments.site/reader035/viewer/2022070801/5f02abd47e708231d4056d7d/html5/thumbnails/26.jpg)
Leak Cannary
26
To find the referenced object in HPROF
To find your leaked object in the hprof file SELECT * FROM INSTANCEOF com.squareup.leakcanary.KeyedWeakReference a WHERE a.key = <Reference Key from Log>
SELECT * FROM INSTANCEOF android.app.Activity a WHERE a.mDestroyed = true
If you don’t have LeakCanary but do have hprof
![Page 27: Leak Canary Intro Jennifer McGee - Meetupfiles.meetup.com/1791179/LeakCanaryIntro.pdfwrite external permissions, but on 6.0 this must be requested at run time Fix: use 1.4-beta1 or](https://reader035.vdocuments.site/reader035/viewer/2022070801/5f02abd47e708231d4056d7d/html5/thumbnails/27.jpg)
27
![Page 28: Leak Canary Intro Jennifer McGee - Meetupfiles.meetup.com/1791179/LeakCanaryIntro.pdfwrite external permissions, but on 6.0 this must be requested at run time Fix: use 1.4-beta1 or](https://reader035.vdocuments.site/reader035/viewer/2022070801/5f02abd47e708231d4056d7d/html5/thumbnails/28.jpg)
28
Questions?
Special Thanks to Bottle Rocket Studios for providing meeting space and allowing me to share this material which is a simplified version of material presentation at a weekly code and tell .
More Resources https://realm.io/news/droidcon-ricau-memory-leaks-leakcanary/
https://github.com/square/leakcanary