Home Item66 (네이티브 메서드는 신중히 사용하라)
Post
Cancel

Item66 (네이티브 메서드는 신중히 사용하라)

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

자바 네이티브 인터페이스(JNI)는 자바 프로그램이 네이티브 메서드를 호출하는 기술이다.

네이티브 메서드는 C나 C++같은 네이티브 프로그래밍 언어로 작성한 메서드를 뜻한다.

전통적으로 이러한 네이티브 메서드의 주요 쓰임은 아래와 같다.

  • 레지스트리 같은 플랫폼 특화 기능을 사용하는 경우
  • 네이티브 코드로 작성된 기존 라이브러리를 사용한 경우
  • 성능 개선을 목적으로 성능에 결정적인 영향을 주는 영역만 따로 네이티브 언어로 작성하는 경우

플랫폼 특화 기능을 활용하려면 네이티브 메서드를 사용해야 한다. 그러나 자바가 발전해가면서 하부 플랫폼의 기능들을 흡수하고 있어 그 필요성이 줄어들고 있다.

따라서 이러한 네이티브 메서드는 경우에 맞게, 조심해서 사용해야 한다. 이유를 알아보자.

네이티브 메서드

우선 네이티브 메서드에 대해 알아보자.

  • 자바 클래스 정의
1
2
3
4
5
6
7
8
9
10
11
12
public class NativeExample {
	public native void printMessage();

	static {
		System.loadLibrary("native-lib");
	}

	public static void main(String[] args) {
		NativeExample example = new NativeExample();
		example.printMessage();
	}
}
  • C 코드 작성
1
2
3
4
5
6
7
#include <jni.h>
#include <stdio.h>
#include "NativeExample.h"

JNIEXPORT void JNICALL Java_NativeExample_printMessage(JNIEnv * env, jobject obj) {
	printf("Hello from C!\n");
}
  • 헤더 파일 생성
1
2
javac NativeExample.java 
javah NativeExample
  • C코드 컴파일 및 네이티브 라이브러리 생성
1
gcc -shared -o libnative-lib.so -I${JAVA_HOME}/include -I${JAVA_HOME}/include/linux NativeExample.c
  • 프로그램 실행
1
java -Djava.library.path=. NativeExample
  • 위 과정들을 거쳐 네이티브 메서드를 사용할 수 있게 된다.
  • 자바 코드의 printMessage() 메서드는 네이티브 메서드이고, 이 메서드의 실제 구현이 C 코드에 있는 것이다.
  • 자바 코드에서 네이티브 라이브러리를 로드하며 해당 라이브러리는 C 코드로 작성된 메서드의 구현체를 포함한다.

네이티브 메서드의 단점

  • 복잡성이 증가한다.
    • 위 코드를 보다시피 네이티브 메서드를 사용하면 코드의 복잡성이 증가한다.
    • 자바 코드와 네이티브 코드 간의 상호작용을 관리해야 한다.
      • 자바 클래스와 C 코드를 모두 작성하고 JNI를 통해 상호작용해야 한다.
  • 이식성이 떨어진다.
    • 네이티브 코드는 특정 플랫폼에 종속적이다. 따라서 자바 프로그램의 이식성을 저하시킨다.
      • 위의 예시에서는 Linux에서 C코드를 컴파일했다.
      • 따라서 Windows나 Mac에서 실행하기 위해 별도의 라이브러리를 생성해주어야 한다.
  • 네이티브 메서드는 안전하지 않다.
    • 가장 중요한 단점이다.
    • 네이티브 코드에서 발생하는 오류는 JVM까지 영향을 미쳐 프로그램의 안전성을 해칠 수 있다.
    • C 코드에서 잘못된 메모리 접근이 발생할 경우 JVM이 충돌할 수 있다.
  • 메모리 관리가 어렵다.
    • 자바는 가비지 컬렉션을 이용해 메모리를 관리해주지만, 네이티브 코드는 그렇지 않아 관리가 어렵다.

네이티브 메서드는 성능 개선 목적으로 사용 X

이제는 성능 개선의 목적으로는 네이티브 메서드를 사용하는 것을 거의 권장하지 않는다.

  • 현대 자바의 JVM은 높은 수준의 최적화를 수행할 수 있다.
    • 따라서 자바 코드를 최적화하는 것이 더 효율적일 수 있다.
  • 디버깅이 어렵다.
    • 네이티브 코드에서 발생하는 버그를 찾고 수정하는 것이 매우 까다롭다.
  • 안전하지 않다.

주의하지 않으면 오히려 속도가 느려질 수도 있다.

정리

네이티브 메서드를 사용하는 목적은 다양할 수 있다.

하지만 현대의 자바는 많은 개선이 이루어졌으며 특히 성능 개선을 위한 목적이라면 네이티브 메서드는 득보다 실이 많다.

만약 네이티브 메서드를 사용할 것이라면 네이티브 코드는 최소한만 사용하고 철저히 테스트해야 한다.

네이티브 코드 안에 숨은 하나의 버그가 애플리케이션 전체를 훼손시킬 수 있다.

This post is licensed under CC BY 4.0 by the author.

Item65 (리플렉션보다는 인터페이스를 사용하라)

Item67 (최적화는 신중히 하라)