임동문의 횡설수설

dmlim.egloos.com

포토로그


라이프로그


Java JNI DLL 언로드

출처

문제

  • System.load()나 System.loadLibrary()로 DLL 모듈을 한번 로드하고 난뒤에, 어떻게 언로드할까?
  • 이론적으로 native 메소드가 구현된 클래스를 로딩한 ClassLoader가 가비지 컬렉트 되지 않으면 DLL을 언로드할 방법이없다.

클래스 로더는 언제 가비지 컬렉트 될까?

  • 자신이 로드한 모든 오프젝트가 가비지 컬렉트 되면 자신도 가비지 컬렉트 된다.
  • 물론 클래스 로더에 대한 레퍼런스들이 모두 null 이어야 한다.

어떤 클래스 로더를 써야 하나?

커스텀 클래스 로더를 이용하여 DLL을 언로드 하는 예제

다음과 같이 navive 메소드를 가진 클래스 A 를 만든다.

package com.codethesis.example;

public class A {
 public A() {}

 static {
  System.loadLibrary("mydll");
 }

 public native void print();

 public void finalize() {
  System.out.println("A garbage collected");
 }
}


print() 메소드가 구현된 mydll.dll 을 만들어서 클래스 패스에 넣는다..
JNI example 은
http://java.sun.com/developer/onlineTraining/Programming/JDCBook/jniexamp.html여기에서 참고하시길
그리고, 테스트 클래스를 만든다.


package com.codethesis.example;

import java.lang.reflect.Method;

public class Test {
 public static void main(String[] args) throws Exception {
  CustomClassLoader cl = new CustomClassLoader();
  Class ca = cl.findClass("com.codethesis.example.A");
  Object a = ca.newInstance();
  Method p = ca.getMethod("print");
  p.invoke(a);
  p = null;
  ca = null;
  a = null;
  cl = null;
  System.gc();
 }
}


System.gc() 가 호출된 뒤에 클래스 로더가 가비지 컬랙트 되면, DLL도 언로드 될것이다.



왜 사용하기 귀찮게 Java reflection 을 썼나?

"a" 오르젝트를 그냥 "A" 클래스로 캐스팅할 수도 있지 않는가?

package com.codethesis.example;

import java.lang.reflect.Method;

public class Test {
 public static void main(String[] args) throws Exception {
  CustomClassLoader cl = new CustomClassLoader();
  Class ca = cl.findClass("com.codethesis.example.A");
  A a = (A)ca.newInstance(); //a ClassCastException is thrown!
  a.print();
  ca = null;
  a = null;
  cl = null;
  System.gc();
 }
}


실제로는 불가능하다. "A" 클래스는 디폴트 클래스로더에 의해서 생성이 되었고.
"a" 오프젝트는 커스텀 클래스로더에 의해서 생성이 되었기 때문에, 서로 다른 클래스가 된다.
그리하여, 인터페이스를 이용한 쉬운 대안을 마련했다.

IA 인터페이스를 작성한다.


package com.codethesis.example;

public interface IA {
 public void print();
}


IA 를 구현한 클래스 A를 다시 만든다.


package com.codethesis.example;

public class A implements IA {
 public A() {}

 static {
  System.loadLibrary("mydll");
 }

 public native void print();

 public void finalize() {
  System.out.println("A garbage collected");
 }
}


그리고 아래와 같이 테스트 코드를 작성 한다.


package com.codethesis.example;

public class Test {
 public static void main(String[] args) throws Exception {
  CustomClassLoader cl = new CustomClassLoader();
  Class ca = cl.findClass("com.codethesis.example.A");
  IA ia = (IA)ca.newInstance();
  ia.print();
  ca = null;
  ia = null;
  cl = null;
  System.gc();
 }
}


 


핑백

덧글

댓글 입력 영역