- Today
- Total
일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
1 | 2 | |||||
3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 | 11 | 12 | 13 | 14 | 15 | 16 |
17 | 18 | 19 | 20 | 21 | 22 | 23 |
24 | 25 | 26 | 27 | 28 | 29 | 30 |
- 재능이의 돈버는 일기
- StresslessLife
- K_JIN2SM
- 소소한 일상
- My Life Style & Memory a Box
- Blog's generation
- 공감 스토리
- 취객의 프로그래밍 연구실
- Love Me
- Dream Archive
- 세상에 발자취를 남기다 by kongmingu
- hanglesoul
- 카마의 IT 초행길
- 느리게.
- 미친듯이 즐겨보자..
- Joo studio
- Gonna be insane
- 악 다 날아갔어!! 갇대밋! 왓더...
- xopowo05
- 맑은공기희망운동
- 엔지니어 독립운동
- 혁준 블로그
- Simple in Complex with Simple
- 무의식이 의식을 지배한다
드럼치는 프로그래머
[JNI/NDK] JNI 사용시 메모리 관리 본문
갑자기 잘되던 프로그램이 안된다...
당황하다가 다시 마음을 잡고 천천히 디버깅 해보았다.
Native와 JAVA 사이에 연결되는 함수가 호출되다가 죽는다.
아래와 같이 반복문이 15회정도 반복되는 함수였다.
float correctCount = 0.0f; for( int i = 0; i < 30; i++ ) { if( jni_GetPUnlocked( s, i ) == true ) { correctCount++; } }
jni_GetPUnlocked 함수는 JAVA함수를 C언어로 읽어들여 체크하는 함수였다.
함수 내용은 아래와 같다.
bool jni_GetPUnlocked(int game, int question) { JNIEnv *env; jclass jNativesCls; bool pUnlocked = false; if ( !g_VM ) { return pUnlocked; } g_VM->AttachCurrentThread ( &env, NULL); jNativesCls = env->FindClass("com/jni/Natives"); if ( jNativesCls == 0 ) { return pUnlocked; } jmethodID mid = env->GetStaticMethodID(jNativesCls , "GetPUnlocked" , "(II)Z"); if (mid) { pUnlocked = env->CallStaticBooleanMethod(jNativesCls , mid , game , question ); data.pUnlocked[game][question] = pUnlocked; } return pUnlocked; }
문제가 없어보인다.
기존에 잘 작동 했었고;;
하지만 갑자기 아래와 같은 에러 메세지를 뱉어내고 프로그램이 죽었다.
04-19 09:27:16.062: WARN/dalvikvm(6702): ReferenceTable overflow (max=512)
04-19 09:27:16.062: WARN/dalvikvm(6702): Last 10 entries in JNI local reference table:
04-19 09:27:16.062: WARN/dalvikvm(6702): 502: 0x40568828 cls=Ljava/lang/Class; 'Lcom/jni/Natives;' (212 bytes)
04-19 09:27:16.062: WARN/dalvikvm(6702): 503: 0x40568828 cls=Ljava/lang/Class; 'Lcom/jni/Natives;' (212 bytes)
04-19 09:27:16.062: WARN/dalvikvm(6702): 504: 0x40568828 cls=Ljava/lang/Class; 'Lcom/jni/Natives;' (212 bytes)
04-19 09:27:16.062: WARN/dalvikvm(6702): 505: 0x40568828 cls=Ljava/lang/Class; 'Lcom/jni/Natives;' (212 bytes)
04-19 09:27:16.062: WARN/dalvikvm(6702): 506: 0x40568828 cls=Ljava/lang/Class; 'Lcom/jni/Natives;' (212 bytes)
04-19 09:27:16.062: WARN/dalvikvm(6702): 507: 0x40568828 cls=Ljava/lang/Class; 'Lcom/jni/Natives;' (212 bytes)
04-19 09:27:16.062: WARN/dalvikvm(6702): 508: 0x40568828 cls=Ljava/lang/Class; 'Lcom/jni/Natives;' (212 bytes)
04-19 09:27:16.062: WARN/dalvikvm(6702): 509: 0x40568828 cls=Ljava/lang/Class; 'Lcom/jni/Natives;' (212 bytes)
04-19 09:27:16.062: WARN/dalvikvm(6702): 510: 0x40568828 cls=Ljava/lang/Class; 'Lcom/jni/Natives;' (212 bytes)
04-19 09:27:16.062: WARN/dalvikvm(6702): 511: 0x40568828 cls=Ljava/lang/Class; 'Lcom/jni/Natives;' (212 bytes)
04-19 09:27:16.062: WARN/dalvikvm(6702): JNI local reference table summary (512 entries):
04-19 09:27:16.062: WARN/dalvikvm(6702): 510 of Ljava/lang/Class; 212B (1 unique)
04-19 09:27:16.062: WARN/dalvikvm(6702): 1 of Ljava/lang/Class; 356B
04-19 09:27:16.062: WARN/dalvikvm(6702): 1 of Ljava/lang/String; 28B
04-19 09:27:16.062: WARN/dalvikvm(6702): Memory held directly by tracked refs is 596 bytes
04-19 09:27:16.062: ERROR/dalvikvm(6702): Failed adding to JNI local ref table (has 512 entries)
대충봐도 메모리 문제로 오버플로우 났다 이런것이였다.
음 먼가 모르던 메모리 관리를 해야 하는건가? 메모리 대여폭을 증가시키는 설정값이라도 있나? 의문이 들었다.
열심히 구글링 한 결과 아래 웹페이지를 찾을수 있었다.
http://java.sun.com/docs/books/jni/html/refs.html#27567
대충 앞부분만 봐도 JNI를 이용할때 메모리 관리를 간과하기 쉽다고 잘하란다=ㅁ=;
위 Native함수를 아래와 같이 수정하니 정상 동작한다.
bool jni_GetPUnlocked(int game, int question)
{
JNIEnv *env;
jclass jNativesCls;
bool pUnlocked = false;
if ( !g_VM ) {
return pUnlocked;
}
g_VM->AttachCurrentThread ( &env, NULL);
jNativesCls = env->FindClass("com/jni/Natives");
if ( jNativesCls == 0 ) {
return pUnlocked;
}
jmethodID mid = env->GetStaticMethodID(jNativesCls
, "GetPUnlocked"
, "(II)Z");
if (mid) {
pUnlocked = env->CallStaticBooleanMethod(jNativesCls
, mid
, game
, question );
data.pUnlocked[game][question] = pUnlocked;
}
// 수정된 부분
env->DeleteLocalRef( jNativesCls );
return pUnlocked;
}
Native에서 생성한 지역변수에 대한 메모리 관리를 해야 한다는 내용이였다.
예전 책에서 봤던 코드는 env->FindClass("com/jni/Natives"); 로 호출하여 받아온 변수를 전역변수로 하나 들고
다시 호출 안하고 했었는데 전역변수 두기가 번거로워서 지역변수로 매번 얻어왔던게 화근이였다.
매번 얻어와도 해제만 잘해줬으면 되는데...알리가 있나-ㅁ-;;
새벽까지 삽질하다가 자고 일어나니 바로 찾아지는 이 기쁨
다행이다-ㅁ-;
'★─Programing > ☆─JNI | NDK' 카테고리의 다른 글
[JNI/NDK] JNI string type 다루는 법 (0) | 2013.06.04 |
---|---|
[JNI/NDK] JNI Tutorial - Exceptions (0) | 2013.05.31 |
[JNI/NDK] ReleaseByteArrayElements 고찰 (0) | 2013.05.31 |
[JNI/NDK] JNI(Java Native Interface) 프로그래밍 방법 (0) | 2013.05.06 |
[JNI/NDK] Java 메소드 시그니쳐 확인 (JNI Signature) (0) | 2013.04.22 |