Programing/Java
Effective Java - Reference
안중환
2016. 2. 29. 14:34
JAVA의 객체가 garbage collection 대상이 되는 순간은?
1. reference가 영원히 영역을 벗어남 (ex. 지역 변수로 선언한 객체의 메소드의 영역을 벗어남)
2. reference에 다른 객체를 대입
3. reference를 직접 'null'로 설정
but, 위 방법 외에 참조를 약하게 만들어 GC 대상이 되도록 만들 수 있다.
Strong Reference > Soft Reference > Weak Reference > Phantom Reference
- Strong Reference
: 일반적으로 new를 통해서 객체를 생성하게 되면 생기게 되는 참조.
: 참조에 대해서 해지하지 않는다면 그 메모리는 절대 수거되지 않는다. - Soft Reference
: GC에 의해 수거될 수도 있고, 수거되지 않을 수도 있다.
: 메모리 상태에 따라 결정 - Weak Reference
: GC가 발생하기 전까지는 참조를 유지한다.
: GC가 발생하는 순간 무조건 수거된다.
: 객체 캐시에 유용 (안드로이드에서 그림이 포함된 listView 등) - Phantom Reference
: 가장 약한 참조
: GC가 발생 전 메모리에서 정리된다. (finalize() 호출 후)
: 내부적으로 유지하고 있지만, 객체를 다시 꺼내오면 null 이다
- ReferenceTest.javapackage kr.co.ioacademy; //iocademy 윤찬식 강사님 import java.lang.ref.SoftReference; import java.lang.ref.WeakReference; import java.util.LinkedList; import java.util.List; // 강한 참조(Strong Reference) // 일반적으로 new를 통해서 객체를 생성하게 되면 생기게 되는 참조. // 강한 참조를 통해 참조되고 있는 객체는 절대 가비지 컬렉션의 대상에서 // 제외된다. // 자바에서 아무리 자동적으로 메모리가 수거된다고 하지만, // 참조에 대해서 해지하지 않는 다면 그 메모리는 절대 수거되지 않는다. // (참조 = null , 참조 = 다른객체) // OutOfMemory를 방지하기 위해서는 약한 형태의 참조를 사용해야 한다. // SoftReference<>, WeakReference<> // Soft Reference // 생성 방법 : SoftReference<Data> r // = new SoftReference<Data>(new Data); // 동작 : 강한 참조와 다르게 GC에 의해 수거될 수도 있고, 수거되지 않을 수도 있다. // 메모리에 충분한 여유가 있다면 GC가 수행되고 있다고 하더라도 수거되지 않는다. // 하지만 out of memory의 시점이 가깝다면, 수거될 확률이 높다. // Weak Reference //생성 방법 : WeakReference<Data> r // = new WeakReference<Data>(new Data); // WeakReference에 의해 참조된 객체는 가비지 컬렉션이 발생하기 전까지는 참조를 유지 // 하지만 GC가 발생하는 순간 무조건 수거된다. // WeakReference가 사라지는 시점이 GC의 실행 주기와 일치한다. // 이를 이용하면 짧은 주기에 자주 사용되는 객체를 캐시할 때 유용하다. // => WeakHashMap // WeakHashMap<K,V> // PhantomReference class BigData { private int[] array = new int[5000]; // 20000byte, 20K } public class ReferenceTest { private List<WeakReference<BigData>> refs = new LinkedList<>(); public void referenceTest() { try { for (int i = 0; true; i++) { refs.add(new WeakReference<BigData>(new BigData())); } } catch (OutOfMemoryError ofm) { // Strong일 경우 out of memory 발생 System.out.println("out of memory!"); } } public static void main(String[] args) { System.out.println("run"); // Thread.sleep(10 * 1000); ReferenceTest test = new ReferenceTest(); test.referenceTest(); System.out.println("finish"); } }
- WeakSingleton.javapackage kr.co.ioacademy; //iocademy 윤찬식 강사님 import java.lang.ref.WeakReference; public class WeakSingleton { private static WeakReference<WeakSingleton> instance = new WeakReference<WeakSingleton>(null); public static WeakSingleton getInstance() { WeakSingleton m = instance.get(); if (m != null) return m; synchronized (WeakSingleton.class) { System.out.println("Create new instance"); m = new WeakSingleton(); instance = new WeakReference<WeakSingleton>(m); } return m; } public static void main(String[] args) { WeakSingleton w = WeakSingleton.getInstance(); // System.gc(); w = WeakSingleton.getInstance(); } }