- 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 | 31 |
- 재능이의 돈버는 일기
- 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 동작원리 개념 - 1 본문
아래 그림은 JNI 를 사용하는 방법은 시작 프로그램에 따라 2가지가 있다.
- Java class -> JNI -> C/C++ library : java 에서 native function 을 호출하는 경우
- C/C++ library -> JNI -> Java class : c/c++ program에서 java 의 함수를 이용하는 경우
이 중에서, 아래 글은 Java 에서 native function 을 호출하는 경우에 대한 이야기이다.
Java -> C/C++
java program은 결국 JVM 에서 실행된다. 이 JVM이 byte code 를 실행하다가 native 함수를 보면 JNI 를 통해 맞는 native 함수를 호출하게 된다. 여기서 JNI 는 JVM 의 일부이기 때문에 아래서 얘기하는 JNI 는 JVM 의 뜻도 같이 가지고 있다고 생각 하자.java program 에서
System.loadLibrary("foo");
로 c/c++ library 를 load 하게 된다. JVM 은 이 때 이 load 된 library 의 "함수 심볼"들을 뒤져서
JNI_OnLoad()
를 찾아서 함수를 호출한다. 이게 없으면,java program에서 호출한 native 함수와 mapping 되는 함수이름을 찾아 놓는다.[ref. 1]
순수한 c/c++ 로 된 함수
이 때 c/c++ library 의 함수가 순수하게 c/c++ 로만 짜여져 있다면 JNI 은 크게 할 일이 없다. 그냥 c/c++ 함수가 끝나서 return 해주면 그 때 다시 java program 으로 돌아가서 계속 프로그램을 수행하면 된다.
Java 의 함수를 이용해야 하는 c/c++
그런데 이 c/c++ 함수가 java program의 class 를 이용해야 한다면 얘기는 달라진다. 이 때부터 c/c++가 java 를 이용하기 위해 JNI 가 가지고 있는 기능(함수) 를 사용해야 한다.이것을 위해 native 함수(c/c++ 함수)에서는 JNIEnv env* 가 parameter 로 넘어온다. 이 env 를 가지고 JNI 가 가지고 있는 기능(함수) 들을 사용할 수 있는 것이다.
이 함수들이 하는 일은 크게 2가지로 나눌 수 있다. 하나는 c/c++ library 안의 함수에서 원하는 변수(field) 나 함수(method) 를 찾아서 가져다 주는 것이고, 다른 하나는 c/c++ library 안의 함수가 java 의 변수에 값을 변경하거나(set), 함수를 호출(call) 할 수 있도록 해주는 것이다.
- get field / method
- set field / call method
- id
- signature
- class name
NewGlobalRef()
이런 식으로 사용된 변수나 함수들은 전부 JNI 를 통해 만들어서 reference 를 native 함수(c/c++ library 함수)로 전달되어진다. 이렇게 JNI에서 전달되는 reference 는 global 과 local , 2종류로 되어있다. 그리고 대부분의 native 함수로 전달되는 reference 는 local reference 이다.
그래서 c/c++ library 에 static 변수를 둬서 java instance 의 reference 를 저장해 놨을 때 주의해야 한다. 그냥 일반적으로 만든 instance 들은 JNI가 함수가 끝나는 시점에 사용하지 않는 녀석으로 되어버린다.(실제로 memory 를 free 하는 것은 JVM 에서 알아서 하는 것이기 때문에 내용이 남아 있을 수는 있지만 사용할 수는 없다.) 그러므로 계속 사용하는 녀석으로 남아있기 위해 NewGlobalRef() / DeleteGlobalRef() 를 사용해야 한다.
이렇게 만들어진 Reference 는 DeleteGlobalRef() 를 통해 명시적으로 삭제하겠다고 얘기하지 않는 이상 JVM이 지우지 않는다. 그러므로 c/c++ library 에서 java instance 를 static 변수에 저장 해서 이용하려면 NewGlobalRef() 를 이용하도록 하자.
Local reference 를 명시적으로 지워야 하는 상황[ref.3]
대부분에 local reference 들은 return 하면서 GC(garbage collector) 가 지울 수 있는 상태가 된다. 하지만 ref. 3 에서 2가지 경우에 명시적으로 local reference 를 지우라고 한다.- local reference 가 참조하는 object 가 memory를 많이 먹는 큰 object 인 경우, 이 경우에는 native 함수가 local reference 를 지우지 않고 있어서 garbabe collector 가 그 object 를 못 지우는 경우가 생길 수 있기 때문에 이런 녀석은 제때에 지우라고 한다.
- local reference 를 너무 많이 사용하는 경우, local reference 를 추적하는 데에도 VM 이 일정량의 memory 를 사용해야 한다고 한다. 그렇기 때문에 너무 많은 local reference 를 사용하면 메모리를 다 써버릴 수도 있다.
Reference
- 인사이드 안드로이드
- http://i5on9i.egloos.com/4840655
- http://docs.oracle.com/javase/7/docs/technotes/guides/jni/spec/design.html
'★─Programing > ☆─JNI | NDK' 카테고리의 다른 글
[JNI/NDK] JNI 동작원리 개념 - 2 (0) | 2016.07.19 |
---|---|
[JNI/NDK] JNI Local Reference Changes in ICS ( ICS 부터 바뀌는 JNI Local Reference ) (0) | 2016.06.03 |
[JNI/NDK] 여러 폴더에 있는 라이브러리 링크하기 (0) | 2016.06.02 |
[JNI/NDK] Android NDK Overview ( 안드로이드 NDK 개요 ) (0) | 2016.05.31 |
[JNI/NDK] 이미 만들어진 so 파일 링크하기 (for 안드로이드) (0) | 2016.05.25 |