nuking nasty memory leaks
play

Nuking nasty memory leaks Pierre-Yves Ricau Pierre-Yves Ricau - PowerPoint PPT Presentation

LeakCanary Nuking nasty memory leaks Pierre-Yves Ricau Pierre-Yves Ricau dependencies { }A dependencies { debugCompile 'com.squareup.leakcanary:leakcanary-android:1.5' releaseCompile


  1. 
 
 
 
 class NeoMobRealismView$1 extends LifecycleCallbacks { 
 private final NeoMobRealismView this$0; 
 public NeoMobRealismView$1(NeoMobRealismView this$0) { 
 this.this$0 = this$0; 
 } 
 @Override public void onActivityResumed(Activity activity) { 
 this$0.animate().alpha(1); 
 } 
 @Override public void onActivityPaused(Activity activity) { 
 this$0.animate().alpha(0); 
 } 
 } public class NeoMobRealismView extends View { 
 public NeoMobRealismView(Context context, AttributeSet attrs) { 
 super(context, attrs); 
 setBackgroundColor(getResources().getColor(R.color. ikb )); 


  2. In com.example.leakcanary:1.0:1. * com.example.leakcanary.MainActivity has leaked: * GC ROOT static android.app.ActivityThread.sCurrentActivityThread * references android.app.ActivityThread.mInitialApplication * references com.example.leakcanary.ExampleApplication.mActivityLifecycleCallbacks * references java.util.ArrayList.elementData * references array java.lang.Object[].[5] * references com.example.leakcanary.NeoMobRealismView$1.this$0 (anonymous subclass of com.example.leakcanary.ActivityLifecycleCallbacksAdapter) * references com.example.leakcanary.NeoMobRealismView.mContext * leaks com.example.leakcanary.MainActivity instance * Retaining: 673 B. * Reference Key: 8b2e09ef-1ea7-48da-b09e-7bf337f64473 * Device: LGE google Nexus 5X bullhead * Android Version: 7.0 API: 24 LeakCanary: 1.6-SNAPSHOT 050b554 * Durations: watch=1296983ms, gc=210ms, heap dump=33311ms, analysis=125485ms * Details: * Class android.app.ActivityThread | static DEBUG_BROADCAST = false | static TWO_COUNT_COLUMNS = java.lang.String@1873829608 (0x6fb05ee8) | static sCurrentActivityThread = android.app.ActivityThread@851460352 (0x32c04100) | static DEBUG_BACKUP = false

  3. * Details: * Class android.app.ActivityThread | static DEBUG_BROADCAST = false | static TWO_COUNT_COLUMNS = java.lang.String@1873829608 (0x6fb05ee8) | static sCurrentActivityThread = android.app.ActivityThread@851460352 (0x32c04100) | static DEBUG_BACKUP = false | static LOG_AM_ON_RESUME_CALLED = 30022 | static DEBUG_RESULTS = false | static LOG_AM_ON_STOP_CALLED = 30049 | static ONE_COUNT_COLUMN_HEADER = java.lang.String@1873816328 (0x6fb02b08) | static DEBUG_ORDER = false | static sPackageManager = android.content.pm.IPackageManager$Stub$Proxy@851448320 (0x32c01200) | static THUMBNAIL_FORMAT = android.graphics.Bitmap$Config@1879418296 (0x7005a5b8) | static SERVICE_DONE_EXECUTING_START = 1 | static REPORT_TO_ACTIVITY = true | static DEBUG_MEMORY_TRIM = false | static ACTIVITY_THREAD_CHECKIN_VERSION = 4 | static HEAP_COLUMN = java.lang.String@1873840320 (0x6fb088c0) | static $classOverhead = byte[1223]@1879556985 (0x7007c379) | static SERVICE_DONE_EXECUTING_STOP = 2 | static HEAP_FULL_COLUMN = java.lang.String@1873843888 (0x6fb096b0) | static SERVICE_DONE_EXECUTING_ANON = 0

  4. | [14] = null * Instance of com.example.leakcanary.NeoMobRealismView$1 | static $classOverhead = byte[664]@851688449 (0x32c3bc01) | this$0 = com.example.leakcanary.NeoMobRealismView@852252560 (0x32cc5790) | shadow$_klass_ = com.example.leakcanary.NeoMobRealismView$1 | shadow$_monitor_ = 0 * Instance of com.example.leakcanary.NeoMobRealismView | static $classOverhead = byte[6184]@851804161 (0x32c58001) | mAccessibilityCursorPosition = -1 | mAccessibilityDelegate = null | mAccessibilityTraversalAfterId = -1 | mAccessibilityTraversalBeforeId = -1 | mAccessibilityViewId = -1 | mAnimator = android.view.ViewPropertyAnimator@852248440 (0x32cc4778) | mAttachInfo = null | mAttributes = null | mBackground = android.graphics.drawable.ColorDrawable@852305184 (0x32cd2520) | mBackgroundRenderNode = android.view.RenderNode@852339848 (0x32cdac88) | mBackgroundResource = 0 | mBackgroundSizeChanged = false | mBackgroundTint = null | mBottom = 1098 | mCachingFailed = false | mClipBounds = null

  5. | [14] = null * Instance of com.example.leakcanary.NeoMobRealismView$1 | static $classOverhead = byte[664]@851688449 (0x32c3bc01) | this$0 = com.example.leakcanary.NeoMobRealismView@852252560 (0x32cc5790) | shadow$_klass_ = com.example.leakcanary.NeoMobRealismView$1 | shadow$_monitor_ = 0 * Instance of com.example.leakcanary.NeoMobRealismView | static $classOverhead = byte[6184]@851804161 (0x32c58001) | mAccessibilityCursorPosition = -1 | mAccessibilityDelegate = null | mAccessibilityTraversalAfterId = -1 | mAccessibilityTraversalBeforeId = -1 | mAccessibilityViewId = -1 | mAnimator = android.view.ViewPropertyAnimator@852248440 (0x32cc4778) | mAttachInfo = null | mAttributes = null | mBackground = android.graphics.drawable.ColorDrawable@852305184 (0x32cd2520) | mBackgroundRenderNode = android.view.RenderNode@852339848 (0x32cdac88) | mBackgroundResource = 0 | mBackgroundSizeChanged = false | mBackgroundTint = null | mBottom = 1098 | mCachingFailed = false | mClipBounds = null

  6. 
 
 public class View { 
 AttachInfo mAttachInfo; 
 public boolean isAttachedToWindow() { 
 return mAttachInfo != null; 
 } }

  7. StackTraceElement[] stackTrace = { 
 new StackTraceElement("com.foo.Foo", "bakeBaguette", "Foo.java", 42), 
 new StackTraceElement("com.foo.Bar", "bailarLaBamba", "Bar.java", 7), 
 }; 
 RuntimeException exception = new RuntimeException(); 
 exception.setStackTrace(stackTrace);

  8. 
 
 
 
 public final class BugsnagLeakUploader { 
 public BugsnagLeakUploader() {…} 
 public void uploadLeak(AnalysisResult result, String leakInfo) { 
 Throwable t = exception(result.className, result.leakTrace); 
 bugsnagClient.notify(t, Severity. WARNING , metadata); 
 } 
 private RuntimeException exception(String className, LeakTrace trace) {…} 
 }

  9. 
 
 public final class ViewRootImpl { static final class RunQueue { 
 private final ArrayList<HandlerAction> mActions = new ArrayList<>(); 
 void post(Runnable action) { 
 postDelayed(action, 0); 
 }A 
 void postDelayed(Runnable action, long delayMillis) { 
 HandlerAction handlerAction = new HandlerAction(); 
 handlerAction.action = action; 
 handlerAction.delay = delayMillis; 
 synchronized (mActions) { 
 mActions.add(handlerAction); 
 }B 
 }C }D }E

  10. 
 
 public final class ViewRootImpl { static final class RunQueue { 
 private final ArrayList<HandlerAction> mActions = new ArrayList<>(); 
 void post(Runnable action) { 
 postDelayed(action, 0); 
 }A 
 void postDelayed(Runnable action, long delayMillis) { 
 HandlerAction handlerAction = new HandlerAction(); 
 handlerAction.action = action; 
 handlerAction.delay = delayMillis; 
 synchronized (mActions) { 
 mActions.add(handlerAction); 
 }B 
 }C }D }E

  11. 
 
 public final class ViewRootImpl { static final class RunQueue { 
 private final ArrayList<HandlerAction> mActions = new ArrayList<>(); 
 void post(Runnable action) { 
 postDelayed(action, 0); 
 }A 
 void postDelayed(Runnable action, long delayMillis) { 
 HandlerAction handlerAction = new HandlerAction(); 
 handlerAction.action = action; 
 handlerAction.delay = delayMillis; 
 synchronized (mActions) { 
 mActions.add(handlerAction); 
 }B 
 }C }D }E

  12. 
 
 public final class ViewRootImpl { static final class RunQueue { 
 private final ArrayList<HandlerAction> mActions = new ArrayList<>(); 
 void post(Runnable action) { 
 postDelayed(action, 0); 
 }A 
 void postDelayed(Runnable action, long delayMillis) { 
 HandlerAction handlerAction = new HandlerAction(); 
 handlerAction.action = action; 
 handlerAction.delay = delayMillis; 
 synchronized (mActions) { 
 mActions.add(handlerAction); 
 }B 
 }C }D }EE

  13. 
 
 public final class ViewRootImpl { /** 
 * The run queue is used to enqueue pending work from Views when no Handler 
 * is attached. The work is executed during the next call to 
 * performTraversals on the thread. 
 */ static final class RunQueue { 
 private final ArrayList<HandlerAction> mActions = new ArrayList<>(); 
 void post(Runnable action) { 
 postDelayed(action, 0); 
 }A 
 void postDelayed(Runnable action, long delayMillis) { 
 HandlerAction handlerAction = new HandlerAction(); 
 handlerAction.action = action; 
 handlerAction.delay = delayMillis; 
 synchronized (mActions) { 
 mActions.add(handlerAction); 
 }B 
 }C

  14. 
 
 public final class ViewRootImpl { /** 
 * The run queue is used to enqueue pending work from Views when no Handler 
 * is attached. The work is executed during the next call to 
 * performTraversals on the thread. 
 */ static final class RunQueue { 
 private final ArrayList<HandlerAction> mActions = new ArrayList<>(); 
 void post(Runnable action) { 
 postDelayed(action, 0); 
 }A 
 void postDelayed(Runnable action, long delayMillis) { 
 HandlerAction handlerAction = new HandlerAction(); 
 handlerAction.action = action; 
 handlerAction.delay = delayMillis; 
 synchronized (mActions) { 
 mActions.add(handlerAction); 
 }B 
 }C

  15. public class View { public void postOnAnimation(Runnable action) { 
 AttachInfo attachInfo = mAttachInfo; 
 if (attachInfo != null) { 
 attachInfo.mViewRootImpl.mChoreographer.postCallback( 
 Choreographer. CALLBACK_ANIMATION , action, null); 
 } else { 
 ViewRootImpl. getRunQueue ().post(action); 
 }A 
 }B public boolean post(Runnable action) { 
 final AttachInfo attachInfo = mAttachInfo; 
 if (attachInfo != null) { 
 return attachInfo.mHandler.post(action); 
 }E 
 ViewRootImpl. getRunQueue ().post(action); 
 return true; 
 }C }D

  16. public class View { public void postOnAnimation(Runnable action) { 
 AttachInfo attachInfo = mAttachInfo; 
 if (attachInfo != null) { 
 attachInfo.mViewRootImpl.mChoreographer.postCallback( 
 Choreographer. CALLBACK_ANIMATION , action, null); 
 } else { 
 ViewRootImpl. getRunQueue ().post(action); 
 }A 
 }B public boolean post(Runnable action) { 
 final AttachInfo attachInfo = mAttachInfo; 
 if (attachInfo != null) { 
 return attachInfo.mHandler.post(action); 
 }E 
 ViewRootImpl. getRunQueue ().post(action); 
 return true; 
 }C }D

  17. public class View { public void postOnAnimation(Runnable action) { 
 AttachInfo attachInfo = mAttachInfo; 
 if (attachInfo != null) { 
 attachInfo.mViewRootImpl.mChoreographer.postCallback( 
 Choreographer. CALLBACK_ANIMATION , action, null); 
 } else { 
 ViewRootImpl. getRunQueue ().post(action); 
 }A 
 }B public boolean post(Runnable action) { 
 final AttachInfo attachInfo = mAttachInfo; 
 if (attachInfo != null) { 
 return attachInfo.mHandler.post(action); 
 }E 
 ViewRootImpl. getRunQueue ().post(action); 
 return true; 
 }C }D

  18. public class View { public void postOnAnimation(Runnable action) { 
 AttachInfo attachInfo = mAttachInfo; 
 if (attachInfo != null) { 
 attachInfo.mViewRootImpl.mChoreographer.postCallback( 
 Choreographer. CALLBACK_ANIMATION , action, null); 
 } else { 
 ViewRootImpl. getRunQueue ().post(action); 
 }A 
 }B public boolean post(Runnable action) { 
 final AttachInfo attachInfo = mAttachInfo; 
 if (attachInfo != null) { 
 return attachInfo.mHandler.post(action); 
 }E 
 ViewRootImpl. getRunQueue ().post(action); 
 return true; 
 }C }D

  19. 
 public final class ViewRootImpl { static final ThreadLocal<RunQueue> sRunQueues = new ThreadLocal<>(); static RunQueue getRunQueue() { 
 RunQueue queue = sRunQueues .get(); 
 if (queue != null) { 
 return queue; 
 }A 
 queue = new RunQueue(); 
 sRunQueues .set(queue); 
 return queue; 
 }B }C

  20. 
 public final class ViewRootImpl { static final ThreadLocal<RunQueue> sRunQueues = new ThreadLocal<>(); static RunQueue getRunQueue() { 
 RunQueue queue = sRunQueues .get(); 
 if (queue != null) { 
 return queue; 
 }A 
 queue = new RunQueue(); 
 sRunQueues .set(queue); 
 return queue; 
 }B }C

  21. 
 public final class ViewRootImpl { static final ThreadLocal<RunQueue> sRunQueues = new ThreadLocal<>(); static RunQueue getRunQueue() { 
 RunQueue queue = sRunQueues .get(); 
 if (queue != null) { 
 return queue; 
 }A 
 queue = new RunQueue(); 
 sRunQueues .set(queue); 
 return queue; 
 }B }C

  22. 
 public final class ViewRootImpl { static final ThreadLocal<RunQueue> sRunQueues = new ThreadLocal<>(); static RunQueue getRunQueue() { 
 RunQueue queue = sRunQueues .get(); 
 if (queue != null) { 
 return queue; 
 }A 
 queue = new RunQueue(); 
 sRunQueues .set(queue); 
 return queue; 
 }B }C

Download Presentation
Download Policy: The content available on the website is offered to you 'AS IS' for your personal information and use only. It cannot be commercialized, licensed, or distributed on other websites without prior consent from the author. To download a presentation, simply click this link. If you encounter any difficulties during the download process, it's possible that the publisher has removed the file from their server.

Recommend


More recommend