2

I'm trying to use JNI code in my android apps.I call a native mehod frequently which return a 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);

After manipulating these variables I released them like this:

    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;
 }

My apps crashes and I have this in my 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)

Any ideas why the overflow is happening? what am I doing wrong?

4

1 回答 1

3

If you are keeping a reference to the returned float arrays they will not be deleted and you will reach the limit for JNI local references.

from your other method in comments:

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

You have to release param by using ReleaseFloatArrayElements not with DeleteLocalRef :

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

Additionally unless you are also doing some processing in Java you should just do all the processing in your native code without going back and forth from Java to Native Code. In your design, it seems that you create and fill an array in native code, then return it to Java only to pass it back to another native method. Unless there's a very good reason for doing it this way you could do all the required processing in native code then return the result.

于 2013-05-03T14:00:28.583 回答