2013-11-28 63 views
0

我是一个JNI的新手,在我测试的手机之一,我得到关于ReferenceTable overflow的错误。我知道这与在本机代码中不释放JNI/Java项目有关。我需要释放我修改并返回的JNI数组吗?

我以为我不需要释放任何东西,因为我使用给定的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错误(安卓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

回答

0

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

+0

这是否仍然允许我返回'data'? – Peterdk

+0

主要思想:您应该通知JVM您已经使用阵列工作,并且可以在需要时使用GC释放它。您可以使用'mode'参数指定发布类型: 0 - 拷贝回内容并释放elems缓冲区 JNI_COMMIT - 拷贝回内容但不释放elems缓冲区 JNI_ABORT - 释放缓冲区而不复制可能的更改 – maximus

相关问题