반응형

 

문제/에러

[Android Native] Abort message: 'JNI DETECTED ERROR IN APPLICATION: JNI ERROR (app bug): jclass is an invalid local reference: XXXX

 

오류 설명

요약:  보통 잘못된 로컬 참조를 하게 되면 이 에러가 발생한다.  해결 방법으로는 글로벌 참조를 생성해주어야한다.

 

보통 JNI (Java Native Interface) 오류는 Java와 네이티브 코드(C/C++) 간의 상호작용에서 발생하는데,

 

여기서 발생한 오류 메시지는 'jclass is an invalid local reference'로, 이는 JNI를 사용할 때 참조된 jclass가 유효하지 않다는 것을 의미한다.

이 오류 메시지를 좀 더 풀어서 설명하면:

  • JNI DETECTED ERROR IN APPLICATION: JNI가 애플리케이션에서 오류를 감지했다는 의미입니다.
  • JNI ERROR (app bug): JNI 오류가 애플리케이션 버그로 인한 것임을 나타냅니다.
  • jclass is an invalid local reference: jclass가 잘못된 컬 참조라는 의미입니다.

 이러한 문제는 대개 JNI 사용 시 자주 발생하는 실수 중 하나이다.

구체적으로는 JNI 함수에서 반환된 로컬 참조를 잘못 관리한 경우 발생할 수 있다.  로컬 참조는 특정 JNI 함수 호출이 끝날 때 자동으로 삭제되므로, 이를 올바르게 관리하지 않으면 이런 오류가 발생할 수 있다.

 

해결방법. NewGlobalRef 사용 (글로벌 참조)

 NewGlobalRef는 JNI(Java Native Interface)에서 사용되는 함수로, Java 객체에 대한 글로벌 참조(global reference)를 생성하는 데 사용된다.

 글로벌 참조는 JVM(Java Virtual Machine)이 종료되거나 명시적으로 삭제할 때까지 유효한 객체 참조이다. 이는 로컬 참조(local reference)와 달리 JNI 함수 호출이 끝난 후에도 유효하게 유지된다.

글로벌 참조의 필요한 이유는,
 JNI를 사용할 때, 특정 객체에 대해 오랜 기간 동안 참조를 유지해야 할 때가 있다. 로컬 참조는 JNI 함수 호출이 끝날 때 자동으로 삭제되기 때문에, 함수 호출 간에 객체를 참조하고 싶다면 글로벌 참조를 사용해야 한다.

예시:

#include <jni.h>

jstring globalStr;

JNIEXPORT void JNICALL Java_com_example_CreateGlobalRef(JNIEnv *env, jobject obj) {
    // Java String 객체 생성
    jstring str = (*env)->NewStringUTF(env, "Hello, JNI!");

    // 글로벌 참조 생성
    globalStr = (jstring)(*env)->NewGlobalRef(env, str);
}

JNIEXPORT void JNICALL Java_com_example_DeleteGlobalRef(JNIEnv *env, jobject obj) {
    // 글로벌 참조 삭제
    if (globalStr != NULL) {
        (*env)->DeleteGlobalRef(env, globalStr);
        globalStr = NULL;
    }
}

 

글로벌 참조 관리
 글로벌 참조를 생성한 후에는 JVM이 종료되기 전이나 더 이상 필요하지 않을 때 명시적으로 삭제해야 한다.

그렇지 않으면 메모리 누수가 발생할 수 있다. DeleteGlobalRef 함수를 사용하여 글로벌 참조를 삭제한다.

글로벌 참조의 주의사항
 글로벌 참조는 JVM의 힙 메모리에 할당되므로, 필요 이상으로 많이 생성하면 메모리 사용량이 증가할 수 있다.
생성된 글로벌 참조는 반드시 DeleteGlobalRef를 사용하여 삭제해야 한다.

반응형