Java Phantom Reference Sample
Java의 reference에는 4가지가 있다.
자세한 내용은 java.lang.ref 문서를 참고.
이중 phantom reference는 잘 쓰이지 않고 샘플 코드도 찾아보기 힘든데 괜찮아 보이는 샘플 코드가 보여 이를 포스팅 해 본다.
실행은 vm option으로 -Xmx1m -Xms1m 을 주고 실행하면 된다.(heap 사이즈 1m로 설정 옵션)
출처: https://www.logicbig.com/tutorials/core-java-tutorial/gc/phantom-reference.html
- Strong reference
- Soft reference
- Weak reference
- Phantom reference
자세한 내용은 java.lang.ref 문서를 참고.
이중 phantom reference는 잘 쓰이지 않고 샘플 코드도 찾아보기 힘든데 괜찮아 보이는 샘플 코드가 보여 이를 포스팅 해 본다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | package ref.phantom; public class MyObject { private int[] ints = new int[1000]; private final String name; public MyObject(String name) { this.name = name; } @Override public String toString() { return name; } @Override protected void finalize() throws Throwable { System.out.printf("%s is finalizing.%n", name); } } |
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 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 | package ref.phantom; import java.lang.ref.PhantomReference; import java.lang.ref.Reference; import java.lang.ref.ReferenceQueue; public class PhantomRefExample { public static void main(String[] args) { ReferenceQueue<MyObject> referenceQueue = new ReferenceQueue<>(); MyObject myObject1 = new MyObject("phantom"); MyObject myObject2 = new MyObject("normal"); Reference<MyObject> ref = new PhantomReference<>(myObject1, referenceQueue); System.out.println("ref#get(): " + ref.get()); // make objects unreachable myObject1 = null; myObject2 = null; if (checkObjectGced(ref, referenceQueue)) { takeAction(); } System.out.println("-- do some memory intensive work --"); for (int i = 0; i < 10; i++) { int[] ints = new int[100000]; try { Thread.sleep(10); } catch (InterruptedException e) { System.out.println("interrupted..."); } } if (checkObjectGced(ref, referenceQueue)) { takeAction(); } } private static boolean checkObjectGced(Reference<MyObject> ref, ReferenceQueue<MyObject> referenceQueue) { boolean gced = false; System.out.println("-- Checking whether object garbage collection due --"); Reference<? extends MyObject> polledRef = referenceQueue.poll(); System.out.println("polledRef: " + polledRef); System.out.println("Is polledRef same: " + (gced = (polledRef == ref))); if (polledRef != null) { System.out.println("Ref#get(): " + polledRef.get()); } return gced; } private static void takeAction() { System.out.println("pre-mortem cleanup actions"); } } |
실행은 vm option으로 -Xmx1m -Xms1m 을 주고 실행하면 된다.(heap 사이즈 1m로 설정 옵션)
MyObject에 finalize를 override 한것은 gc 되는지 확인해 보기 위한 것이다. 참고로 finalize와 cleaner(java9)는 사용하지 않도록 권고하고 있다.(Effective Java 3rd Item9 참고)
댓글
댓글 쓰기