Skip to content

Latest commit

 

History

History
132 lines (88 loc) · 5.08 KB

네이티브_메서드는_신중히_사용하라.md

File metadata and controls

132 lines (88 loc) · 5.08 KB

자바 네이티브 인터페이스(Java Native Interface, JNI)

  • 네이티브 메서드를 호출하는 기술

  • 네이티브 메서드 사용법

  1. 아래와 같이 작성
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());
   }
}
  1. 터미널에서 javah 명령어로 헤더 파일 생성
    • C or C++ 을 구현할 수 있는 파일
  2. 네이티브 메서드 구현
  3. 3에서 만든 소스 코드를 공유 라이브러리로 등록

네이티브 메서드

  • C나 C++같은 네이티브 프로그래밍 언어로 작성한 메서드

  • 네이티브 메서드의 주요 쓰임 세 가지

  1. 레지스트리 같은 플랫폼 특화 기능 사용

    • 자바가 성숙해지면서 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();
}
  1. 네이티브 코드로 작성된 기존 라이브러리 사용

    • 대체할 만한 자바 라이브러리가 없는 네이티브 라이브러리를 사용해야 할 때는 네이티브 메서드 사용
  2. 성능 개선을 목적으로 성능에 결정적인 영향을 주는 영역만 따로 네이티브 언어로 작성

    • 성능을 개선할 목적으로 네이티브 메서드를 사용하는 것은 거의 권장 X
    • JVM이 엄청난 속도로 발전하여, 대부분 작업에서 지금의 자바는 다른 플랫폼에 견줄만한 성능을 보인다.
    • ex) BigInteger
      • java 1.1 때는 C 의 고성능 라이브러리 의존
      • java 3 때 순수 자바로 만듦
      • 다만 이후로 8 때의 곱셈 성능 개선 이외로 커다란 변화 X
  3. 이식성

    • 네이티브 언어는 자바보다 플랫폼을 많이 타서 이식성도 낮고 디버깅도 더 어렵다.
  4. 메모리 훼손 오류

    • 네이티브 언어가 안전하지 않으므로 네이티브 메서드를 사용하는 어플리케이션도 메모리 훼손 오류로부터 더 이상 안전하지 않다.

    • 가비지 컬렉터가 네이티브 메모리는 자동 회수하지 못하고, 심지어 추적조차 할 수 없다.

  5. 성능과 비용, 가독성

    • 주의하지 않으면 속도가 오히려 느려질 수 있다.
    • 자바 코드와 네티이브 코드의 경계를 넘나들 때마다 비용도 추가된다.
    • 네이티브 메서드와 자바 코드 사이의 접착 코드(glue code) 이는 귀찮은 작업이거니와 가독성도 떨어진다.
      • 접착 코드
        • 프로그램의 요구사항 구현에는 기여하지 않지만, 본래 호환성이 없는 부분끼리 결합하기 위해 작동하는 코드