Wednesday, April 20, 2011

Android Thread Pool Leak - Process, AsyncTask, or ScheduledThreadPoolExecutor?

I recently tracked down a thread leak in Net Ping.

It was the ScheduledThreadPoolExecutor.

To execute pings, the app uses these thread resources: AsyncTask, Process, and a ScheduledThreadPoolExecutor.

The AsyncTask is used to run the ping on a non-UI thread. Pinging can often take too long to complete on a UI thread, and anything that blocks the UI thread for five seconds will display the ANR (Application Not Responsive) error to the user.

The Process is how the ping is executed. Since Android restricts the network driver's capabilities to prevent normal, non-rooted apps from opening a socket for pinging, we need to use the native OS's ping command, which has the sticky bit set. The OS's ping command runs as the administrator, and is granted unrestricted access to the network device.

The ScheduledThreadPoolExecutor is used to time the responses coming back from the ping execution. Sometimes, ping may block for a very long time, particularly if there are intermittent network errors. The thread executor is used to spawn Runnables that will kill a hung, unresponsive ping process.

In the case of Net Ping, the AsyncTask starts up to five threads, and resuses those threads on subsequent ping operations. No leaks observed with AsyncTask.

The Process doesn't actually start a new thread in the context of the app. When using a Process object, it's important to call destroy() on it to ensure that the external process is terminated, and any related streams are closed.

Finally, we get to where the leak occurred: after the ScheduledThreadPoolExecutor object no longer had any references to it, it would not terminate the threads that were idle and waiting for work that could never possibly come. The fix was to call shutdownNow() followed by awaitTermination() just before the executor object goes out of scope, and we lose the last reference to it.

Net Ping version 1.7 has this fix, and is available in the Android Market. Enjoy!

1 comment:

  1. I like the app but i would like to see a few things added. Im also a developer but y reinvent the wheel? :D
    I have a network that uses several servers, cameras and its on a mesh network. So I had found a need to developed a quick script for windows that does the following:
    1) allows the user to ping a range of addresses
    2) allows the user to ping a group of non ranged and ranged addresses together
    3) allow to change the default values (TTL, number tries, ect)
    4) can save and load ranges

    think you can add something like this to the product? If so, this would be very helpfull because I would rather like to test specific parts of my network while on the go, instead of walking back to the specific computer and running my script. Thank you