Mobile Development 11 min read

How to Diagnose and Fix OOM Crashes Caused by Thread Pool Misuse in Android Apps

This guide explains how to identify OutOfMemoryError crashes in Android applications caused by excessive thread‑pool creation, using tools like Android CPU Profiler, adb ps commands, and code hooks, and provides concrete steps to refactor OkHttp, RxJava, and SDK usage to prevent resource leaks.

Maoyan Technology Team
Maoyan Technology Team
Maoyan Technology Team
How to Diagnose and Fix OOM Crashes Caused by Thread Pool Misuse in Android Apps

1. Background

During development an OOM (OutOfMemoryError) crash was observed across many pages. The stack trace showed failures in thread pool creation, with the app reporting up to 1456 threads, far exceeding normal usage.

2. Investigation Methods

2.1 Android CPU Profiler

The CPU Profiler can display all created threads, their names and states, helping to locate the source of the thread explosion.

2.2 adb ps command

Using adb shell ps | grep <package> to find the process ID, then adb shell ps -T | grep <pid> to list all threads. The watch -n 1 -d 'adb shell ps -T | grep u0_a589 | wc -l' command can monitor thread count in real time.

watch -n 1 -d 'adb shell ps -T | grep u0_a589 | wc -l'

2.3 Hooking Thread Creation

Using the epic library to hook Thread constructors and log stack traces when threads are created.

private void hookThread() {
    DexposedBridge.hookAllConstructors(Thread.class, new XC_MethodHook() {
        @Override
        protected void afterHookedMethod(MethodHookParam param) throws Throwable {
            Thread thread = (Thread) param.thisObject;
            Log.d(ThreadMethodHook.TAG, "Thread: " + thread.getName() + " stack:" + Log.getStackTraceString(new Throwable()));
        }
    });
}

2.4 Problem Confirmation

Combining crash logs and thread‑pool analysis revealed that an SDK’s OkHttp client and RxJava’s Schedulers.newThread() were repeatedly creating new threads and OkHttpClient instances, leading to uncontrolled thread growth and OOM.

// Example of creating a new OkHttpClient each request
Dispatcher dispatcher = new Dispatcher(Executors.newSingleThreadScheduledExecutor());
return new OkHttpClient.Builder().dispatcher(dispatcher).build();
Observable.create(...).subscribeOn(Schedulers.newThread())...

3. Solution

Remove Schedulers.newThread() usage for logging tasks.

Reuse a single OkHttpClient instance instead of creating a new one per request.

Limit SDK calls that create thread pools by adding request‑count and time‑interval constraints.

Configure thread pools with allowCoreThreadTimeOut to let idle core threads terminate.

4. Summary

To prevent OOM caused by thread‑pool misuse in Android apps, monitor thread creation with profiling tools or adb, avoid creating new OkHttpClient or RxJava threads for each operation, centralize thread‑pool configuration, and apply timeout policies. These steps stabilize thread counts and eliminate memory leaks.

DebuggingPerformanceAndroidThreadPoolRxJavaOOMOkHttp
Maoyan Technology Team
Written by

Maoyan Technology Team

Code your life of light and shadow

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.