【问题标题】:DeleteGlobalRef crash on ICSICS 上的 DeleteGlobalRef 崩溃
【发布时间】:2012-10-09 15:31:15
【问题描述】:

我使用 NDK 为 Java 分配大缓冲区:

allocNativeBuffer(JNIEnv* env, jobject cls, jlong size) {
    void* buffer = malloc(size);
    jobject directBuffer = env->NewDirectByteBuffer(buffer, size);
    jobject globalRef = env->NewGlobalRef(directBuffer);
    return globalRef;
}

使用此缓冲区后,我将其释放:

freeNativeBuffer(JNIEnv* env, jobject cls, jobject globalRef) {
    void *buffer = env->GetDirectBufferAddress(globalRef);
    env->DeleteGlobalRef(globalRef);
    free(buffer);
}

在 Android 2.2 上它可以正常工作,但在 Android 4.0.3 上,应用程序在 DeleteGlobalRef 调用期间崩溃。我做错了什么?

【问题讨论】:

    标签: android crash android-ndk


    【解决方案1】:

    在 ICS 中对全局和局部引用的实现进行了彻底检查,旨在改进 Java 端的内存管理。在developers guide 中找到解释,在developers blog 中阅读更多信息。

    简而言之,无论您在 JNI 函数中收到什么,包括 freeNativeBuffer() 函数的 globalRef 参数,都是本地引用。您可以在 C 代码中创建并保留全局引用,如下所示:

    static jobject globalRef;
    
    allocNativeBuffer(JNIEnv* env, jobject cls, jlong size) {
        void* buffer = malloc(size);
        jobject directBuffer = env->NewDirectByteBuffer(buffer, size);
        globalRef = env->NewGlobalRef(directBuffer);
        return directBuffer;
    }
    
    freeNativeBuffer(JNIEnv* env, jobject cls, jobject localRef) {
        void *buffer = env->GetDirectBufferAddress(localRef);
        if (buffer == env->GetDirectBufferAddress(globalRef) {
            /* we received the object that we saved */
            env->DeleteGlobalRef(globalRef);
            free(buffer);
        }
    }
    

    PS 我找到了stackoverflow discussion,这看起来像是您实验的灵感来源。请参阅answer,它解释说首先不需要创建和删除全局引用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2023-03-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多