-
네이티브 메서드를 호출하는 기술
-
네이티브 메서드 사용법
- 아래와 같이 작성
public class ExampleJNI {
static {
System.loadLibrary("EdenJNI");
}
private native int getNumber();
public static void main(String[] args) {
ExampleJNI jni = new ExampleJNI();
System.out.println(jni.getNumber());
}
}
- 터미널에서 javah 명령어로 헤더 파일 생성
- C or C++ 을 구현할 수 있는 파일
- 네이티브 메서드 구현
- 3에서 만든 소스 코드를 공유 라이브러리로 등록
-
C나 C++같은 네이티브 프로그래밍 언어로 작성한 메서드
-
네이티브 메서드의 주요 쓰임 세 가지
-
레지스트리 같은 플랫폼 특화 기능 사용
- 자바가 성숙해지면서 OS 같은 하부 플랫폼의 기능들을 점차 흡수.
- 네이티브 메서드를 사용할 필요가 계속 줄어듦.
- 예시) Java 9 Process API
public class JavaProcess {
public static void main(String[] args) {
ProcessHandle processHandle = ProcessHandle.current();
System.out.println(ProcessHandle.of(processHandle.pid()).orElse(null));
System.out.println("Native process ID of the process: " + processHandle.pid()); // process id
System.out.println("\nDirect children: " + processHandle.children());
System.out.println("\nClass name: " + processHandle.getClass());
System.out.println("\nAll processes: " + ProcessHandle.allProcesses());
System.out.println("\nProcess info: " + processHandle.info());
System.out.println("\nIs process alive: " + processHandle.isAlive());
System.out.println("\nProcess's parent " + processHandle.parent());
//Process snapshot of the current running process with ProcessHandle.Info:
ProcessHandle.Info processInfo = processHandle.info();
System.out.println("\nProcess snapshot of the current running process:");
System.out.println("User : " + processInfo.user().get());
System.out.println("Start Time : " + processInfo.startInstant().get());
}
}
출력 결과:
Native process ID of the process: 71961
Direct children: java.util.stream.ReferencePipeline$2@4cb2c100
Class name: class java.lang.ProcessHandleImpl
All processes: java.util.stream.IntPipeline$1@614c5515
Process info: [user: Optional[sungsan], cmd: /Library/Java/JavaVirtualMachines/jdk-11.0.9.jdk/Contents/Home/bin/java, args: [-javaagent:/Applications/IntelliJ IDEA.app/Contents/lib/idea_rt.jar=50766:/Applications/IntelliJ IDEA.app/Contents/bin, -Dfile.encoding=UTF-8, -classpath, /Users/sungsan/woowacourse/study/practice/out/production/practice, item66.JavaProcess], startTime: Optional[2022-03-31T06:37:13.980Z], totalTime: Optional[PT0.388529S]]
Is process alive: true
Process's parent Optional[10197]
Process snapshot of the current running process:
User : sungsan
Start Time : 2022-03-31T06:37:13.980Z
final class ProcessHandleImpl implements ProcessHandle {
static {
initNative();
long pid = getCurrentPid0();
current = new ProcessHandleImpl(pid, isAlive0(pid));
}
private static native long getCurrentPid0();
}
-
네이티브 코드로 작성된 기존 라이브러리 사용
- 대체할 만한 자바 라이브러리가 없는 네이티브 라이브러리를 사용해야 할 때는 네이티브 메서드 사용
-
성능 개선을 목적으로 성능에 결정적인 영향을 주는 영역만 따로 네이티브 언어로 작성
- 성능을 개선할 목적으로 네이티브 메서드를 사용하는 것은 거의 권장 X
- JVM이 엄청난 속도로 발전하여, 대부분 작업에서 지금의 자바는 다른 플랫폼에 견줄만한 성능을 보인다.
- ex) BigInteger
- java 1.1 때는 C 의 고성능 라이브러리 의존
- java 3 때 순수 자바로 만듦
- 다만 이후로 8 때의 곱셈 성능 개선 이외로 커다란 변화 X
-
이식성
- 네이티브 언어는 자바보다 플랫폼을 많이 타서 이식성도 낮고 디버깅도 더 어렵다.
-
메모리 훼손 오류
-
네이티브 언어가 안전하지 않으므로 네이티브 메서드를 사용하는 어플리케이션도 메모리 훼손 오류로부터 더 이상 안전하지 않다.
-
가비지 컬렉터가 네이티브 메모리는 자동 회수하지 못하고, 심지어 추적조차 할 수 없다.
-
-
성능과 비용, 가독성
- 주의하지 않으면 속도가 오히려 느려질 수 있다.
- 자바 코드와 네티이브 코드의 경계를 넘나들 때마다 비용도 추가된다.
- 네이티브 메서드와 자바 코드 사이의
접착 코드(glue code)
이는 귀찮은 작업이거니와 가독성도 떨어진다.- 접착 코드
- 프로그램의 요구사항 구현에는 기여하지 않지만, 본래 호환성이 없는 부분끼리 결합하기 위해 작동하는 코드
- 접착 코드