【问题标题】:Do I need to Release JNI array that I modify and return?我是否需要发布我修改并返回的 JNI 数组?
【发布时间】:2013-12-14 14:41:15
【问题描述】:

我是 JNI 的新手,在我测试的一部手机上,我收到了关于 ReferenceTable overflow 的错误。我知道这与未在本机代码中发布 JNI/Java 项有关。

我以为我不需要释放任何东西,因为我使用给定的jfloatarray,替换它的值,然后再次返回原始 JNI 对象。我认为这会使 JNI 释放对象本身,因为它只是将其取回。

JNI 代码:

extern "C"
JNIEXPORT jfloatArray JNICALL Java_methodname(
        JNIEnv *env, jobject thiz, jfloatArray data)
{
float* nativeValues = (float *)env->GetFloatArrayElements(data, 0);
doSomething(nativeValues);//overwrite the values with new values
return data;
}

JNI 错误(Android 2.3):

11-28 15:00:58.069: W/dalvikvm(833): ReferenceTable overflow (max=1024)
11-28 15:00:58.069: W/dalvikvm(833): Last 10 entries in JNI pinned array reference table:
11-28 15:00:58.069: W/dalvikvm(833):  1014: 0x405f3750 cls=[F (20 bytes)
11-28 15:00:58.069: W/dalvikvm(833):  1015: 0x405f37b0 cls=[F (20 bytes)
11-28 15:00:58.069: W/dalvikvm(833):  1016: 0x405f3810 cls=[F (20 bytes)
11-28 15:00:58.069: W/dalvikvm(833):  1017: 0x405f3870 cls=[F (20 bytes)
11-28 15:00:58.069: W/dalvikvm(833):  1018: 0x405f38d0 cls=[F (20 bytes)
11-28 15:00:58.069: W/dalvikvm(833):  1019: 0x405f3930 cls=[F (20 bytes)
11-28 15:00:58.069: W/dalvikvm(833):  1020: 0x405f3990 cls=[F (20 bytes)
11-28 15:00:58.069: W/dalvikvm(833):  1021: 0x405f39f0 cls=[F (20 bytes)
11-28 15:00:58.069: W/dalvikvm(833):  1022: 0x405f3a50 cls=[F (20 bytes)
11-28 15:00:58.069: W/dalvikvm(833):  1023: 0x405f3ab0 cls=[F (20 bytes)
11-28 15:00:58.074: W/dalvikvm(833): JNI pinned array reference table summary (1024 entries):
11-28 15:00:58.074: W/dalvikvm(833):  1020 of [F 20B (1020 unique)
11-28 15:00:58.074: W/dalvikvm(833):     4 of [F 28B (4 unique)
11-28 15:00:58.074: W/dalvikvm(833): Memory held directly by tracked refs is 20512 bytes
11-28 15:00:58.074: E/dalvikvm(833): Failed adding to JNI pinned array ref table (1024 entries)

我该怎么办?将数据值复制到新的float* 并用它创建一个新的jfloatarray

【问题讨论】:

    标签: java android java-native-interface


    【解决方案1】:

    当您通过GetFloatArrayElements(..)函数获取元素时,由于JVM将其标记为“用于本机代码”,因此您需要释放数组元素。 为此请致电ReleaseFloatArrayElements()。 在那里查看详细信息: http://docs.oracle.com/javase/6/docs/technotes/guides/jni/spec/functions.html#wp17440

    【讨论】:

    • 这还能让我退回data吗?
    • 主要思想:您应该通知 JVM,您希望使用数组,如果需要,它可以使用 GC 释放它。您可以使用mode 参数指定发布类型:0 - 复制回内容并释放 elems 缓冲区 JNI_COMMIT - 复制回内容但不释放 elems 缓冲区 JNI_ABORT - 释放缓冲区而不复制回可能的更改
    猜你喜欢
    • 1970-01-01
    • 2017-06-17
    • 2011-01-26
    • 1970-01-01
    • 2023-03-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多