2015-11-20 41 views
0

所以我注意到我的应用程序在重复调用以下方法后崩溃。对JNI方法的重复调用使应用程序崩溃

JNIEXPORT void JNICALL Java_com_kitware_VolumeRender_VolumeRenderLib_DummyFunction(JNIEnv * env,jobject obj, jlong udp, jdoubleArray rotation, jdoubleArray translation){ 
    jboolean isCopy1, isCopy2 ; 
    jdouble* rot = env->GetDoubleArrayElements(rotation,&isCopy1); 
    jdouble* trans = env->GetDoubleArrayElements(translation,&isCopy2); 

    if(isCopy1 == JNI_TRUE){ 
    env->ReleaseDoubleArrayElements(rotation,rot, JNI_ABORT); 
    } 
    if(isCopy2 == JNI_TRUE){ 
    env->ReleaseDoubleArrayElements(translation,trans, JNI_ABORT); 
    } 

} 

我以为这将是由于一些缺失的内存空间,但我在这里释放内存不是吗?仍然在512次调用该方法后,我的应用崩溃了。

如果需要的话我可以为您提供Logcat但它是一个相当长的一个。经过一番调查,我很确定这个错误出现在内存分配/释放过程中(即,无论我调用函数多少次,注释掉两个GetDoubleArrayElements()都会让我运行一个应用程序)。

回答

1

在Android的文档:http://developer.android.com/training/articles/perf-jni.html

它明确规定:

必须释放每个数组你获取。另外,如果Get调用失败,则必须确保您的代码不会尝试稍后释放NULL指针。

只要我记得你的代码超过的本地引用数量的限制。所以你应该删除这些检查:if(isCopy2 == JNI_TRUE){

不过,上述文件对JNI_ABORT一个段落,这说明它可能连同isCopy使用 - 但它有点混乱。你可能会寻找关于如何使用Android的JNI_ABORT来源,即这里是一些代码:

http://androidxref.com/6.0.0_r1/xref/frameworks/ml/bordeaux/learning/multiclass_pa/jni/jni_multiclass_pa.cpp#77

在我的代码我经常用PushLocalFrame/PopLocalFrame防止局部引用泄漏。

+0

感谢您的回答。无论如何,绝对有助于释放它们。所以从我读的内容以及如果我理解正确的话,一个好的方法是:if(isCopy1 == JNI_TRUE)env-> ReleaseDoubleArrayElements(rotation,rot,JNI_ABORT); } else { env-> ReleaseDoubleArrayElements(rotation,rot,0); } 如果(isCopy1 == JNI_TRUE){ env-> ReleaseDoubleArrayElements(平移,反式,JNI_ABORT); } else { env-> ReleaseDoubleArrayElements(translation,trans,0); }“我对吗?如果我是你,你可能想把它添加到你的答案。无论如何,anser接受和upvoted的文档和建议。 – LBes

+0

@LBes我会说,在这里检查isCopy没有意义,如果你看看源代码:http://androidxref.com/6.0.0_r1/xref/art/runtime/jni_internal.cc#ReleasePrimitiveArray,你会看到当isCopy == false时,此函数不是检查JNI_ABORT的模式,您还将看到,如果isCopy为false,则此函数在某些情况下执行以下方法:DecrementDisableMovingGC – marcinj

+0

好的谢谢:) – LBes