2010-04-07 7 views
2

나는 C에서 Java로 호출하는 JNI 호출 API에서 작업 중이다. 전역 참조로 30+ Java 클래스를 캐시하기위한 몇 가지 초기 초기화가있다. FindClass의 결과는 NewGlobalRef에 전달되어 클래스에 대한 전역 참조를 가져옵니다. 나중에이 클래스 변수를 캐싱하여 나중에 다시 사용합니다. 클래스에 30 개 이상의 전역 참조가 있고 클래스 생성자에 대해 30 개 이상의 전역 methodID가 있습니다.JNI 캐시 된 jclass 전역 참조 변수가 가비지 수집됩니까?

다음 샘플에서는 코드 단편을 줄이기 위해 예외 처리와 JNI 호출을 제거했습니다. 내 작업 코드는 모든 JNI 호출 후에 예외 검사를하고 -Xcheck : jni를 사용하여 실행합니다. 여기 단편이다 :

jclass aClass; 
jclass bClass; 

jmethodID aCtor; 
jmethodID bCtor; 

void getGlobalRef(const char* clazz, jclass* globalClass) 
{ 
    jclass local = (*jenv)->FindClass(jenv,clazz); 
    if (local) 
    { 
    *globalClass = (jclass) (*jenv)->NewGlobalRef(jenv,local); 
    (*jenv)->DeleteLocalRef(jenv,local); 
    } 
} 

methodID getMethodID(jclass clazz, const char* method, const char* sig) 
{ 
    return (*jenv)->GetMethodID(jenv,clazz,method,sig); 
} 

void initializeJNI() 
{ 
    getGlobalRef("MyProj/Testclass1", &aclass); 
    getGlobalRef("MyProj/Testclass2", &bclass); 
    . 
    . 
    aCtor = getMethodID(aclass,"<init>","()V"); 
    bCtor = getMethodID(bclass,"<init>","(I)V"); 

} 

initializeJNI() 함수는 생성자뿐만 아니라 일부 jfieldID는 C의 및 데이터 구조의 일부 초기화 jclasses 방법 및 ID의 전역 참조를 설정한다.

캐시 된 jclass와 ctor jmethodID 중 일부를 사용하여 JNI 함수를 호출하면 초기화 된 후에 -Xcheck : jni에서보고 된 잘못된 전역 또는 로컬 참조 호출이 발생합니다.

gdb에서 initializeJNI()의 마지막 줄에서 깨지고 모든 jclasses와 jmethodIDs를 인쇄하면 문제를 일으키는 원인이 가비지 수집되거나 가비지 수집 (예 : 0x00 또는 0x06) 된 것으로 보입니다. 글로벌 참조가 가능할 수 있습니까?

제안 사항?

+0

해결되었습니다. C.의 데이터 손상 JNI 오류가 없습니다. – bubbadoughball

답변

3

죄송합니다.

해결되었습니다. C에서의 데이터 손상 일부 메모리를 쾅쾅 치는 것은 캐시 된 JNI 변수의 손실을 초래했습니다.

JNI 오류가 없습니다.

+0

나는 JNI 문제라고 생각한 많은 문제점을 가지고있다. JNI 문제로 C/C++ 코드 (해제 된 변수, 버퍼 덮어 쓰기 등)에서 잘못된 메모리 관리로 밝혀졌다. JNI 문제 참조! –

관련 문제