Android的JNI - 呼叫AttachCurrentThread没有DetachCurrentThread [英] Android JNI - Call AttachCurrentThread without DetachCurrentThread

查看:3455
本文介绍了Android的JNI - 呼叫AttachCurrentThread没有DetachCurrentThread的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我一直在阅读有关JNI的东西,似乎无法弄清楚发生了什么,如果一个线程开始 - >调用AttachCurrentThread() - >使一些JNI调用 - >线程退出

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.

在理想情况下,我们应该线程退出之前调用DetachCurrentThread(),但是,会有什么影响,如果应用程序不这样做呢?它会导致内存泄漏或其他问题?

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?

推荐答案

不调用 DetachCurrentThread()肯定会导致内存泄漏;其他的后果是JVM特有的,大概为Android应用程序,其中JVM关闭时,在进程退出无关。有相当多的C ++包装来帮助管理线程的连接/断开,参见例如:的 http://w01fe.com/blog/2009/05/c-callbacks-into-java-via-jni-made-easyier

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

更新: 1000感谢 法登 作为眼-opening的 链接 ;在Dalvik的,离开不调用线程 DetachCurrentThread(),使整个VM和进程崩溃。

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.

下面是从官方模拟器logcat的基础上,的 HelloJni 从NDK示例:

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)

下面是相关的功能添加到<一个href=\"https://android.googlesource.com/platform/development/+/master/ndk/samples/hello-jni/jni/hello-jni.c\"相对=nofollow> HELLO-jni.c

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 !");
}

这篇关于Android的JNI - 呼叫AttachCurrentThread没有DetachCurrentThread的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆