- mongodb - 在 MongoDB mapreduce 中,如何展平值对象?
- javascript - 对象传播与 Object.assign
- html - 输入类型 ="submit"Vs 按钮标签它们可以互换吗?
- sql - 使用 MongoDB 而不是 MS SQL Server 的优缺点
我一直在阅读有关 JNI 的内容,但似乎无法弄清楚如果线程启动 -> 调用 AttachCurrentThread() -> 进行一些 JNI 调用 -> 线程退出会发生什么。
理想情况下,我们应该在线程退出之前调用 DetachCurrentThread(),但是,如果应用程序不这样做,会有什么影响?它会导致内存泄漏或任何其他问题吗?
最佳答案
不调用DetachCurrentThread()
肯定会造成内存泄漏;其他后果是 JVM 特定的,可能与 Android 应用程序无关,其中 JVM 在进程退出时关闭。有很多 C++ 包装器可以帮助管理线程 Attach/Detach,例如:http://w01fe.com/blog/2009/05/c-callbacks-into-java-via-jni-made-easyier
更新: 1000 感谢 fadden 大开眼界 link ;在 Dalvik 上,一个未调用 DetachCurrentThread()
的线程退出,导致整个 VM 和进程崩溃。
这是官方模拟器的logcat,我的代码基于HelloJni
来自 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)
这里是添加到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 !");
}
可以在 WebRTC git repo 中找到该策略的一个很好的实现。 .
关于Android JNI - 在没有 DetachCurrentThread 的情况下调用 AttachCurrentThread,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26534304/
我有一个由我公司开发的私有(private)库。它允许我设置一个回调函数,这样长时间操作完成后,回调将在子线程中调用。 我应该在回调中操作JVM。这是我在回调函数中的主要代码: JNIEnv *pEn
我正在从 C 代码调用 Java 方法。每次调用时,我调用 AttachCurrentThread,调用后调用 DetachCurrentThread。 这工作正常,但问题是我看到由此引起的连续垃圾收
我很抱歉问了一个非常模糊的问题,但是,我有一个纯原生的 NDK 应用程序,它应该在沉浸模式(即全屏)下执行。 沉浸式模式 JNI fragment 在应用程序通过 APP_CMD_RESUME 恢复时
我一直在阅读有关 JNI 的内容,但似乎无法弄清楚如果线程启动 -> 调用 AttachCurrentThread() -> 进行一些 JNI 调用 -> 线程退出会发生什么。 理想情况下,我们应该在
我在使用 lib Vlc for android 的应用程序中收到此警告。 W/art: Native thread exiting without having called DetachCurre
我有一个使用 NDK 的 Android 应用程序 - 一个具有常规 UI 和 C++ 核心的常规 Android Java 应用程序。在核心中有些地方我需要调用 Java 方法,这意味着我需要该线程
我是一名优秀的程序员,十分优秀!