c++ - 引用表溢出(最大值=1024)

标签 c++ opencv memory-management java-native-interface

我正在尝试在我的 Android 应用程序中使用 JNI 代码。我经常调用 native 方法,该方法返回 jfloatArray:

JNIEXPORT jfloatArray JNICALL Java_com_qualcomm_QCARSamples_ImageTargets_DetectionBasedTracker_getvaluenative
(JNIEnv *env, jclass, jlong thiz,jfloatArray feature)
{   //  these are my variables
   CvMat* cameraMat = cvCreateMat(3,3,CV_32F);
   CvMat* distMat =cvCreateMat(4,1,CV_32F);
   jfloat* flt1 = env->GetFloatArrayElements(feature,0);
   CvMat* imageMat = cvCreateMat(5,2,CV_32F);
   CvMat* objMat = cvCreateMat(5,3,CV_32F);
   CvMat* vec1 = cvCreateMat(1,3,CV_32F);
   CvMat* vec2 = cvCreateMat(1,3,CV_32F);
   Mat rotM ;
   Mat m(vec1);
   Mat t(vec2);
   Mat rotM1 = rotM.t();
   CvMat n = rotM1;
   CvMat translat= t;
   jfloatArray resultArray = env->NewFloatArray(12 );
   float matrice[12];
    env->SetFloatArrayRegion(resultArray, 0,12 ,matrice);

操作这些变量后,我像这样释放它们:

    cvReleaseMat(&vec1);
    cvReleaseMat(&vec2);
    cvReleaseMat(&distMat);
    cvReleaseMat(&cameraMat);
    cvReleaseMat(&imageMat);
    cvReleaseMat(&objMat);
    rotM.release();
    rotM1.release();
    m.release();
    t.release();
env->ReleaseFloatArrayElements(feature, flt1, 0);
    env->DeleteLocalRef(feature);
    return resultArray;
 }

我的应用程序崩溃了,我的 Logcat 中有此内容:

05-02 13:41:03.179: W/dalvikvm(11288): ReferenceTable overflow (max=1024)
05-02 13:41:03.179: W/dalvikvm(11288): JNI pinned array reference table (0x32e248) dump:
05-02 13:41:03.179: W/dalvikvm(11288):   Last 10 entries (of 1024):
05-02 13:41:03.179: W/dalvikvm(11288):      1023: 0x4105ad68 float[] (10 elements)
05-02 13:41:03.179: W/dalvikvm(11288):      1022: 0x4106d220 float[] (12 elements)
05-02 13:41:03.179: W/dalvikvm(11288):      1021: 0x41071db0 float[] (12 elements)
05-02 13:41:03.179: W/dalvikvm(11288):      1020: 0x4106d610 float[] (12 elements)
05-02 13:41:03.179: W/dalvikvm(11288):      1019: 0x4106d508 float[] (12 elements)
05-02 13:41:03.179: W/dalvikvm(11288):      1018: 0x4106efb0 float[] (12 elements)
05-02 13:41:03.179: W/dalvikvm(11288):      1017: 0x41072698 float[] (12 elements)
05-02 13:41:03.179: W/dalvikvm(11288):      1016: 0x410870c8 float[] (12 elements)
05-02 13:41:03.179: W/dalvikvm(11288):      1015: 0x4106cb88 float[] (12 elements)
05-02 13:41:03.179: W/dalvikvm(11288):      1014: 0x41087268 float[] (12 elements)
05-02 13:41:03.179: W/dalvikvm(11288):   Summary:
05-02 13:41:03.179: W/dalvikvm(11288):         1 of float[] (10 elements)
05-02 13:41:03.179: W/dalvikvm(11288):      1023 of float[] (12 elements) (1023 unique instances)
05-02 13:41:03.179: E/dalvikvm(11288): Failed adding to JNI pinned array ref table (1024 entries)

你知道为什么会发生溢出吗?我做错了什么?

最佳答案

如果您保留对返回 float 组的引用,它们将不会被删除,并且您将达到 JNI 本地引用的限制。

来自评论中的其他方法:

param= (env->GetFloatArrayElements(imageArray,0)); 
then i have release it : env->DeleteLocalRef(imageArray);

您必须使用 ReleaseFloatArrayElements 释放参数,而不是使用 DeleteLocalRef :

env->ReleaseFloatArrayElements(imageArray, param, 0);

此外,除非您也在 Java 中进行一些处理,否则您应该只在 native 代码中进行所有处理,而无需在 Java 和 native 代码之间来回切换。在您的设计中,似乎您在 native 代码中创建并填充了一个数组,然后将其返回到 Java,仅将其传递回另一个 native 方法。除非有充分的理由这样做,否则您可以在 native 代码中完成所有必需的处理,然后返回结果。

关于c++ - 引用表溢出(最大值=1024),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16360634/

相关文章:

C++ Vector 实现分配新对象

c - 我有点困惑,自动内存分配是在运行时还是编译时发生

c++ - 使用 lerp 在两个图像之间执行线性插值

iOS( objective-C )。从数组中获取 block 时应用程序崩溃

c++ - 在数据结构中查找 ""之间的字符串的代码

c++ - 两个类可以同时互相继承吗?

c++ - std::string::find_first_of 未返回预期值

c++ - 分配派生类时使用现有的基类对象

image - OpenCV 可以读取的最大图像是多少?

python - 在Windows上同时安装Python 2和Python 3时,如何为Python 2安装OpenCV