Memory leak refers to allocated memory in a program that is not released or cannot be released for some reason, causing available memory to gradually decrease and eventually leading to OOM (Out Of Memory) crashes.
Common Memory Leak Scenarios
1. Static Variables Holding Activity/Context References
javapublic class Singleton { private static Singleton instance; private Context context; private Singleton(Context context) { this.context = context; // Leak! Holds Activity reference } // Solution: Use ApplicationContext private Singleton(Context context) { this.context = context.getApplicationContext(); } }
2. Non-static Inner Classes/Anonymous Classes
javapublic class MainActivity extends Activity { private Handler handler = new Handler() { // Non-static inner class @Override public void handleMessage(Message msg) { // Holds reference to outer Activity } }; } // Solution: Use static inner class + WeakReference private static class MyHandler extends Handler { private WeakReference<Activity> weakRef; MyHandler(Activity activity) { weakRef = new WeakReference<>(activity); } }
3. Unregistered Listeners and Receivers
java// Memory leak example registerReceiver(receiver, filter); // Forgot to unregisterReceiver in onDestroy // Solution @Override protected void onDestroy() { super.onDestroy(); unregisterReceiver(receiver); }
4. Resources Not Closed
- Database Cursor not closed
- IO streams not closed
- Bitmap not recycled
5. Object References in Collections
javastatic List<Activity> activityList = new ArrayList<>(); // Add Activity but never remove activityList.add(activity);
Memory Leak Detection Tools
1. Android Studio Memory Profiler
- Real-time memory allocation monitoring
- Heap Dump analysis
- View object reference chains
2. LeakCanary
groovydependencies { debugImplementation 'com.squareup.leakcanary:leakcanary-android:2.x' }
- Automatic memory leak detection
- Generate leak reference chains
- Notification of leak information
3. MAT (Memory Analyzer Tool)
- Analyze hprof files
- Find Dominator Tree
- Identify leak suspects
Memory Leak Prevention Strategies
1. Use ApplicationContext
java// When Activity features are not needed Intent intent = new Intent(getApplicationContext(), Target.class);
2. Release Resources Timely
java@Override protected void onDestroy() { super.onDestroy(); // Remove Handler messages and callbacks handler.removeCallbacksAndMessages(null); // Cancel network requests call.cancel(); // Unregister listeners sensorManager.unregisterListener(listener); }
3. Use WeakReference
javaprivate static class MyAsyncTask extends AsyncTask<Void, Void, Void> { private WeakReference<Activity> weakActivity; MyAsyncTask(Activity activity) { weakActivity = new WeakReference<>(activity); } @Override protected Void doInBackground(Void... voids) { // Background task return null; } @Override protected void onPostExecute(Void result) { Activity activity = weakActivity.get(); if (activity != null && !activity.isFinishing()) { // Update UI } } }
4. Use Lifecycle Components
javaclass MyObserver implements DefaultLifecycleObserver { @Override public void onDestroy(LifecycleOwner owner) { // Auto cleanup } }
Key Points
- Understand Java memory model and GC mechanism
- Master reference types: Strong, Soft, Weak, Phantom
- Familiar with common leak scenarios and solutions
- Able to use tools to analyze and locate leaks
- Understand Android memory optimization best practices