Search code examples
androidandroid-ndkjava-native-interface

best strategy for attaching arbitrary threads to Android JVM


I find myself needing to call back into the JVM from arbitrary native threads that may or may not be long-lived. It's easy enough call AttachCurrentThread prior to every Java method invocation on the assumption that it's a (presumably fast) no op if the thread's already attached, but I find myself wondering what the JVM does with attached native threads when they go away somewhere in native-land without being officially detached. Or in other words, is this going to be a problem? If so, then I find myself wondering about the overhead of attaching/detaching for each Java method invocation. Ideally each thread would just register itself upon startup and detach on shutdown but again, I'm writing code that must be callable from arbitrary threads running code that has no idea it's running inside of Android, so that's not a realistic option in this case.

Any thoughts on the matter?


Solution

  • I find myself wondering what the JVM does with attached native threads when they go away somewhere in native-land without being officially detached.

    The regular VM shuts down when all non-daemon threads have exited. Attaching a thread without detaching means that the VM cannot exit and has to wait for your thread to detach first. This is just a general case of VM, though. In Android it shouldn't be a problem, as apps don't really "exit". Source.

    But detaching threads is highly recommended for proper memory management (see an official recommendation).

    I'm writing code that must be callable from arbitrary threads running code that has no idea it's running inside of Android, so that's not a realistic option in this case.

    Actually, the implementation of a self-detaching thread is quite easy. Pass "destructor" reference to pthread_key_create(destKey_, threadDestructor); and inside this "destructor" call JNI method cached_jvm->DetachCurrentThread();.

    Hope that helps!