Mobile Development 17 min read

Android Memory Optimization: Detect Leaks, Cut RAM, Boost Performance

This article outlines comprehensive Android memory optimization strategies, covering leak detection with LeakCanary, system‑level hacks, bitmap handling, runtime monitoring, multi‑process usage, and GC tuning, providing practical code snippets and tools to reduce RAM usage, prevent OOM crashes, and improve app performance.

WeChat Client Technology Team
WeChat Client Technology Team
WeChat Client Technology Team
Android Memory Optimization: Detect Leaks, Cut RAM, Boost Performance

Android Memory Optimization

Optimize RAM to lower runtime memory, preventing OOM exceptions and reducing the chance of being killed by LMK; also reduces GC frequency and improves smoothness.

Optimize ROM to shrink the app package size, avoiding installation failures due to insufficient storage.

The focus of this article is the first point: techniques for reducing runtime memory.

Memory Leak Detection and Fix

A memory leak occurs when an object remains referenced due to coding errors or system issues, preventing garbage collection, increasing memory peaks and OOM risk.

Common causes exist, but establishing a closed‑loop detection and remediation process is the key.

1. Memory Leak Monitoring Solution

Square's open‑source LeakCanary uses weak references to track Activity lifecycles, dumps Hprof on leak detection, and shows the shortest leak path via the HAHA library.

The monitoring flow is illustrated below:

WeChat’s own leak monitoring differs from LeakCanary in three ways:

For Android 4.0+, we register ActivityLifecycleCallbacks ; for older versions we reflect ActivityThread.mInstrumentation . Currently we support Android‑15 and above.

LeakCanary’s dump can cause noticeable UI stalls; WeChat adds stricter detection (three‑time confirmation plus five new Activities) to avoid false positives from system caches.

When a potential leak is found, a dialog prompts the user before dumping and uploading the Hprof; analysis is performed server‑side.

By lightly customizing LeakCanary we can achieve a full leak‑monitoring closed loop:

2. Hack Fix for System Leaks

AndroidExcludedRefs lists system‑level references that cannot be released; WeChat applies similar hacks for TextLine, InputMethodManager, AudioManager, and android.os.Message.

3. Bottom‑up Memory Reclamation

Activity leaks keep Bitmaps, DrawingCache, etc., alive. In onDestroy, recursively release all child view resources so the leaked Activity becomes an empty shell.

Drawable d = iv.getDrawable();
if (d != null) {
    d.setCallback(null);
}
iv.setImageDrawable(null);
...

Overall, a complete leak‑detection and remediation framework, combined with regular testing, is essential.

Methods to Reduce Runtime Memory

When leaks are eliminated, additional techniques help lower RAM usage and reduce OOM probability.

Android OOM behavior:

Android 2.x: OOM occurs when

dalvikAllocated + externalAllocated + newAllocation >= dalvikHeapMax

; Bitmaps count toward external.

Android 4.x and later: External counting removed; Bitmaps allocated in the Java heap. OOM when dalvikAllocated + newAllocation >= dalvikHeapMax.

1. Reduce Bitmap Memory

Key points:

Prevent oversized Bitmaps: enable hidden inNativeAlloc on Android 2.x or use Facebook's Fresco on Android 4.x to allocate Bitmaps in native memory.

Load images on demand: calculate an appropriate inSampleSize so the image size does not exceed the view size.

Use a unified image loader (Picasso, Fresco, or WeChat's ImageLoader) to hide version differences and handle OOM by clearing cache or switching bitmap formats (ARGB_8888, RGB_565, etc.).

Eliminate pixel waste in .9 images by analyzing ARGB values and scaling redundant regions.

A good ImageLoader abstracts these details across Android versions.

2. Self‑Memory Monitoring

System callbacks like onLowMemory are coarse; we need a per‑process monitor that checks Runtime.getRuntime().maxMemory() and

Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory()

to trigger cleanup.

Implementation principle: Runtime.getRuntime().maxMemory() gives the heap limit; the difference between total and free memory is the current usage.

Runtime.getRuntime().maxMemory();
Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();

Operation: periodically (e.g., every 3 minutes) check the usage; if it exceeds a threshold (e.g., 80%), release caches (especially Bitmap caches) and invoke WindowManagerGlobal.getInstance().startTrimMemory(TRIM_MEMORY_COMPLETE) to force GC.

WindowManagerGlobal.getInstance().startTrimMemory(TRIM_MEMORY_COMPLETE);

3. Use Multiple Processes

Components like WebView or image galleries can be moved to separate processes to isolate their memory usage, as WeChat does.

4. Report Detailed OOM Information

When an OOM crash occurs, upload detailed memory state to aid post‑mortem analysis.

Other techniques (large‑heap, inBitmap, SparseArray, Protobuf) are omitted; avoid the "optimize‑then‑embed‑pit" cycle and instead build a robust framework and monitoring system.

GC Optimization

GC pauses can consume frame time, hurting UI smoothness.

1. Types of GC

GC_FOR_ALLOC – synchronous, triggered when allocating objects; most impactful on frame rate.

GC_EXPLICIT – invoked via System.gc() ; runs with low priority and may not happen immediately.

GC_CONCURRENT – asynchronous, triggered when an object >384KB is allocated; frequent occurrences indicate insufficient object reuse.

GC_EXTERNAL_ALLOC – removed after Android 3.0; triggered by native allocation failures (e.g., textures, Bitmaps, ByteBuffers).

2. Memory Churn Phenomenon

Rapid creation and immediate release of many objects cause short‑term memory spikes, leading to frequent GC and possible frame drops.

Memory Monitor can reveal such churn.

3. GC Optimization

Use Heap Viewer to compare snapshots and Allocation Tracker to identify hot allocation paths. WeChat’s tool aggregates allocation data by type and stack, ranking by size and frequency for targeted optimization.

Key optimization actions:

String concatenation – replace ‘+’ with StringBuilder and pre‑set capacity.

Printer logging = me.mLogging;
if (logging != null) {
    logging.println(">>>>> Dispatching to " + msg.target + " " +
            msg.callback + ": " + msg.what);
}

File reading – use ByteArrayPool with pre‑allocated capacity.

Resource reuse – maintain global caches for frequently allocated objects.

Avoid unnecessary objects – minimize allocations in onDraw , getView , loops, etc.

Choose efficient data structures – prefer SparseArray , SparseBooleanArray , LongSparseArray over HashMap .

Summary

Not every optimization technique can be listed, and some become obsolete with new Android versions. The crucial practice is continuous discovery and fine‑grained monitoring rather than ad‑hoc fixes.

Prefer leveraging existing tools; avoid reinventing the wheel and contribute improvements back to the community.

Focus on building a robust framework that prevents issues and enables timely detection.

WeChat’s current memory monitoring system still has shortcomings that need future improvement.

References

Android memory management – http://developer.android.com/intl/zh-cn/training/articles/memory.html

LeakCanary – https://github.com/square/leakcanary

AndroidExcludedRefs – https://github.com/square/leakcanary/blob/master/leakcanary-android/src/main/java/com/squareup/leakcanary/AndroidExcludedRefs.java

Fresco – https://github.com/facebook/fresco

Optimizing Android app memory – http://bugly.qq.com/blog/?p=621

Android performance – memory chapter – http://hukai.me/android-performance-memory/

Original Source

Signed-in readers can open the original source through BestHub's protected redirect.

Sign in to view source
Republication Notice

This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactadmin@besthub.devand we will review it promptly.

PerformanceAndroidMemory Optimizationleak detectionGC tuning
WeChat Client Technology Team
Written by

WeChat Client Technology Team

Official account of the WeChat mobile client development team, sharing development experience, cutting‑edge tech, and little‑known stories across Android, iOS, macOS, Windows Phone, and Windows.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.