Call Static Object Method를 호출하여 JNI DETECTED ERROR IN APPLICATION: jclass is an invalid local reference:

최근에 JNI 문제가 발생했습니다. 코드 한 세트가 안드로이드에서 처음 실행되는 것은 OK입니다. 그러나 두 번째 실행 후에 장치가 붕괴될 것입니다. 로그캣을 보면 JNI DETECTED ERROR IN APPLICATION 오류가 발생했습니다.
  (1)  :
 accessed stale local reference 0x57200019 (index 6 in a table of size 6)
 JNI DETECTED ERROR IN APPLICATION: jclass is an invalid local reference    in call to CallStaticObjectMethod  from void com.org.vincent.ccalljava.JNI.getTime()
JNI DETECTED ERROR IN APPLICATION: calling static method xxxx with CallxxxxMethodV in call to CallxxxxMethodV

위의 오류를 종합하면 Call Static Object Method의 jclass 파라미터가 불법으로 인용된 것으로 보인다. 인터넷에서 관련 문제의 게시물을 찾았는데 JNI에서 사용하지 않는 인용 방식이 세 가지가 있고 서로 다른 방식과 서로 다른 생명주기가 있다는 것을 설명한다.로컬 코드와 결합하여 가장 가능성이 있는 것은 jclass 실례가 국부 인용을 사용할 수 없다는 것이다. 전역 인용을 사용하여 jclass 실례가 함수에서 퇴출된 후에도 생명 주기를 유지해야 한다.
변경 전:
 if(JNI == NULL) {

        JNI = (*jniEnv)->FindClass(jniEnv,"com/org/vincent/ccalljava/JNI");
        if(JNI == NULL){
            return -1;
        }

        __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "InitProvider Begin  2 ok" );
    }

다음으로 변경:
 if(JNI == NULL) {
        jclass localRef;
        localRef = (*jniEnv)->FindClass(jniEnv,"com/org/vincent/ccalljava/JNI");
        if(JNI == NULL){
            return -1;
        }
        //    jclass      
        JNI=(*jniEnv)->NewGlobalRef(jniEnv,localRef);
        __android_log_print(ANDROID_LOG_INFO, "JNIMsg", "InitProvider Begin  2 ok" );
    }

JNI는 jni에서 정의한 전역 변수입니다. 이 함수가 실행되고 종료되면 JNI가 가리키는 jclass 형식의 메모리가 GC에서 회수될 수 있습니다. 그러면 JNI는 불법 주소를 가리킵니다.사후 검증 판정이 맞습니다.

좋은 웹페이지 즐겨찾기