Android JNI - Call AttachCurrentThread without DetachCurrentThread

匿名 (未验证) 提交于 2019-12-03 01:18:02

问题:

I have been reading about JNI stuff and can't seem to figure out what happens if a thread starts -> calls AttachCurrentThread() -> make some JNI calls -> thread exit.

Ideally, we should call DetachCurrentThread() before thread exits, however, what are the implications if the app doesn't do that? Would it cause memory leak or any other problem?

回答1:

Not calling DetachCurrentThread() will definitely cause a memory leak; other consequences are JVM-specific, and probably irrelevant for Android apps, where the JVM shuts down when the process exits. There are quite a few C++ wrappers that help to manage thread Attach/Detach, see for example: http://w01fe.com/blog/2009/05/c-callbacks-into-java-via-jni-made-easyier

Update: 1000 thanks to fadden for the eye-opening link; on Dalvik, a thread that exits without calling DetachCurrentThread(), brings the whole VM and the process crashing down.

Here is the logcat from the official emulator, my code based on the HelloJni sample from NDK:

10-26 04:16:25.853: D/dalvikvm(1554): Trying to load lib /data/app-lib/com.example.hellojni-2/libhello-jni.so 0xb3d264f0 10-26 04:16:25.893: D/dalvikvm(1554): Added shared lib /data/app-lib/com.example.hellojni-2/libhello-jni.so 0xb3d264f0 10-26 04:16:25.893: D/dalvikvm(1554): No JNI_OnLoad found in /data/app-lib/com.example.hellojni-2/libhello-jni.so 0xb3d264f0, skipping init 10-26 04:16:26.463: D/gralloc_goldfish(1554): Emulator without GPU emulation detected. 10-26 04:16:31.033: D/threadFunction(1554): Attaching 10-26 04:16:31.173: D/threadFunction(1554): Not Detaching 10-26 04:16:31.183: D/dalvikvm(1554): threadid=11: thread exiting, not yet detached (count=0) 10-26 04:16:31.193: D/dalvikvm(1554): threadid=11: thread exiting, not yet detached (count=1) 10-26 04:16:31.193: E/dalvikvm(1554): threadid=11: native thread exited without detaching 10-26 04:16:31.193: E/dalvikvm(1554): VM aborting 10-26 04:16:31.213: A/libc(1554): Fatal signal 6 (SIGABRT) at 0x00000612 (code=-6), thread 1567 (xample.hellojni) 

Here is the relevant function added to hello-jni.c:

static JavaVM* jvm = 0; static jobject activity = 0; // GlobalRef  void* threadFunction(void* irrelevant) {     JNIEnv* env;     usleep(5000000);      __android_log_print(ANDROID_LOG_DEBUG, "threadFunction", "Attaching");      (*jvm)->AttachCurrentThread(jvm, &env, NULL);      jclass clazz = (*env)->GetObjectClass(env, activity);     jmethodID methodID = (*env)->GetMethodID(env, clazz, "finish", "()V" );     (*env)->CallVoidMethod(env, activity, methodID);      __android_log_print(ANDROID_LOG_DEBUG, "threadFunction", "Not Detaching"); //    (*jvm)->DetachCurrentThread(jvm); }  jstring Java_com_example_hellojni_HelloJni_stringFromJNI( JNIEnv* env,                                                   jobject thiz ) {     (*env)->GetJavaVM(env, &jvm);     activity = (*env)->NewGlobalRef(env, thiz);      pthread_t hThread;     pthread_create(&hThread, NULL, &threadFunction, NULL);     return (*env)->NewStringUTF(env, "Hello from JNI !"); } 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!