Memory Leaks on Android

Post on 11-Apr-2017

34 views 0 download

Transcript of Memory Leaks on Android

Memory Leaks

SOFTWARE ENGINEER | AUTHOR | CONSULTANTOmri Erez

@innovationMaze | https://medium.com/@OomriErez

WHAT YOU DON’T KNOW WILL DRIVE YOU CRAZY

About Me

Memory Leak

A scenario in which our application persistently retains an object’s memory, even after it is not needed anymore.

The Garbage Collector

Source: https://flic.kr/p/pWwnZf

Component Life Cycle

Activity Life Cycle

App Life Cycle

Service Life Cycle

References TreeGC

Root

O2

O3 O4

Source: https://flic.kr/p/q2TrC7

GC Roots

Static variables

& functions

References on a stack

JNI references

& objects

A Memory LeakGC

Root

O2

O3

O4

Source: https://flic.kr/p/52jkCJ

Source: https://flic.kr/p/6H4wxP

What you don’t know WILL drive you crazy

Scenario 1

private static View mLeakingView; private byte[] mBytes=new byte[1000000]; @Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity); mLeakingView = findViewById(R.id.mainView); mLeakingView.setOnClickListener(view -> finish()); MyStringHelper.getInstance().setActivity(this); Log.d(TAG,MyStringHelper.getInstance().getString(R.string.app_name)); }

Static References

Static Referencespublic final class MyStringHelper { private final static MyStringHelper INSTANCE = new MyStringHelper(); private Context mActivityContext; public static MyStringHelper getInstance() {return INSTANCE;} public void setActivity(Context context) {mActivityContext=context;} public String getString(int id) { return mActivityContext.getString(id); } private MyStringHelper() { if (INSTANCE != null) { throw new IllegalStateException("Already instantiated"); } }}

The Source of the Leak

•Static reference to a view

•Static instance of MyStringHelper

Their lifecycle is longer than the activity lifecycle

A Memory Leak

GC RootmLeakingView

Activity

GC RootMyStringHelper

Solution?

Solution :|

@Overrideprotected void onDestroy() { mLeakingView=null; MyStringHelper.getInstance()

.setActivityContext(null); super.onDestroy(); }

Solution :)

•Avoid static references especially to Android components like activities, services and views

•Use Application context instead of the Activity context

Scenario 2

Anonymous Classes//Anonymous classprivate final Handler mLeakyHandler = new Handler() { @Override public void handleMessage(Message msg) { } }; @Overrideprotected void onCreate(@Nullable Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.activity); mView.setOnClickListener(view -> finish()); mLeakyHandler.sendEmptyMessageDelayed(MESSAGE_ID,20000);}

A Memory Leak

Looper ActivitymLeakyHandler

Source: https://flic.kr/p/6H4wxP

Solution :|

@Overrideprotected void onDestroy() { mLeakyHandler.removeMessages(MESSAGE_ID); super.onDestroy(); }

Solution :)

•When using the Handler class, make sure its static

Scenario 3

Non Static Inner Classes

private class MyRunnable implements Runnable { @Override public void run() { Log.d(TAG, "I am running in activity:" + InnerClassLeakingActivity.this.getComponentName()); } }

Solution :)

•Avoid non-static inner classes

•Use WeakReference if needed

Solution :)private static class MyRunnable implements Runnable{ WeakReference<InnerClassLeakingActivity> mWeakActivity; public MyRunnable(InnerClassLeakingActivity activity) { this.mWeakActivity = new WeakReference<>(activity); } @Override public void run() { final InnerClassLeakingActivity activity=mWeakActivity.get(); if (activity!=null) Log.d(TAG, String.format("I am running in activity:%s" ,activity.getComponentName()));

}}

Tools for Automatic Detection

StrictMode

•Here to help find developers mistakes and bring it to our attention

•Very easy to use

StrictMode :)

if (BuildConfig.DEBUG) { StrictMode.VmPolicy vmPolicy=new StrictMode.VmPolicy.Builder() .detectActivityLeaks()

.detectLeakedSqlLiteObjects() .detectLeakedClosableObjects() .penaltyLog() .build(); StrictMode.setVmPolicy(vmPolicy); }

Leak Canary

•Created by Pierre-Yves Ricau (Square Inc)

•Very easy to use

•Tracks objects for memory leaks

Thank you!

Q & A@innovationMaze | omri.erez.it@gmail.com

https://goo.gl/qtnq0S