-
Notifications
You must be signed in to change notification settings - Fork 44
Open
Description
Description
The com.enrique.stackblur.NativeBlurProcess class utilizes a static instance of ExecutorService initialized as a FixedThreadPool. This thread pool is never shut down.
In the Android environment, this design causes a resource leak (specifically a Thread Leak). Even after the Activity using the blur effect is destroyed (onDestroy), the threads created by the static executor remain in the memory (in a WAITING state) until the entire application process is killed.
Affected Component
- Class:
com.enrique.stackblur.NativeBlurProcess - Line: 16
- Issue Type: Resource Leak / Not Terminated Thread Pool (NT)
Root Cause Analysis
As seen in the source code:
// NativeBlurProcess.java
private static final int EXECUTOR_THREADS = Runtime.getRuntime().availableProcessors();
// Using newFixedThreadPool creates threads that do not expire by default
private static final ExecutorService EXECUTOR = Executors.newFixedThreadPool(EXECUTOR_THREADS);
1. Static Lifecycle: The EXECUTOR is static, binding its lifecycle to the application process, not the Activity lifecycle.
2. FixedThreadPool: Unlike CachedThreadPool, threads in a FixedThreadPool do not terminate when idle (unless allowCoreThreadTimeOut is set). They persist indefinitely.
3. Missing Cleanup: There is no method provided to call shutdown() on the executor.
Steps To Reproduce
1. Open an Android application integrating this library.
2. Trigger a blur operation using NativeBlurProcess. This initializes the static EXECUTOR and creates N threads (where N = CPU cores).
3. Finish/Destroy the current Activity (e.g., press Back).
4. Inspect the application threads using Android Studio Profiler.
Expected Behavior
The worker threads should be released or terminated when the blurring task is complete or when the associated Activity is destroyed.
Actual Behavior
The pool-X-thread-Y threads remain alive and occupy memory (stack memory per thread) even when the app is idling in the background or the specific screen is closed.
Suggested Fixes
I suggest one of the following approaches to resolve this:
Remove static (Recommended) Make the ExecutorService an instance variable. The caller can create an instance of NativeBlurProcess, perform the blur, and the GC will eventually collect it (or the caller can explicitly shut it down).
// Remove static
private final ExecutorService executor;
public NativeBlurProcess() {
executor = Executors.newFixedThreadPool(EXECUTOR_THREADS);
}
// Add cleanup method if needed
public void destroy() {
executor.shutdown();
}Metadata
Metadata
Assignees
Labels
No labels