jni table overflow even after deleteLocalRef

前端 未结 2 1303
忘了有多久
忘了有多久 2021-01-12 19:10

When I run the code, I get an error \"failed adding to JNI local ref table has 512 entries\"

This is my code:

jstring pJNIData = pJNIEnv->NewStrin         


        
2条回答
  •  生来不讨喜
    2021-01-12 19:33

    I have seen this when a JNI method called Java code (in my case, the method was not static). As I understand, unused local references are not automatically deleted when a Java method is called from JNI (I mean, until the top-level JNI function returns).

    IIRC either there already was information about memory objects in the log, or I could add some logging; from that information I identified garbage items that I did not mention before. They were two arrays and a class, created in subsequent calls but not garbage-collected.

    // in a function that calls a Java method from JNI
    jbyteArray srcArray = env->NewByteArray(len);
    jclass cls = env->FindClass("com/something/MyClass");
    jmethodID mid = env->GetMethodID(cls, "mymethod", "([BI)[B");
    jbyteArray resArray = (jbyteArray)env->CallObjectMethod(obj, mid, srcArray, XXXX);
    
    ...
    env->DeleteLocalRef(cls);
    env->DeleteLocalRef(resArray);
    env->DeleteLocalRef(srcArray);
    // no need to do anything with mid
    

    Note that although these three local references were obtained differently, all of them were hanging around.

    Useful link: http://www.netmite.com/android/mydroid/dalvik/docs/jni-tips.html#local_vs_global_references (or find the Dalvik VM docs dalvik/docs/jni-tips.html and locate the section "Local vs. Global References")

    Every object that JNI returns is a "local reference". This means that it's valid for the duration of the current native method in the current thread. Even if the object itself continues to live on after the native method returns, the reference is not valid. This applies to all sub-classes of jobject, including jclass and jarray. [...] Note: method and field IDs are just 32-bit identifiers, not object references, and should not be passed to NewGlobalRef. The raw data pointers returned by functions like GetStringUTFChars and GetByteArrayElements are also not objects.

提交回复
热议问题