강한 참조(Strong Reference)
일반적으로 new를 통해서 객체를 생성하게 되면 생기게 되는 참조.
강한 참조를 통해 참조되고 있는 객체는 가비지 컬렉션의 대상에서 제외된다.
Soft Reference
강한 참조와는 다르게 GC에 의해 수거될 수도 있고, 수거되지 않을 수도 있습니다. 메모리에 충분한 여유가 있다면 GC가 수행되고 잇다 하더라도 수거되지 않습니다. 하지만 out of memory의 시점에 가깝다면 수거될 확률이 높습니다.
약한 참조(Weak Reference)
약한 참조는 GC가 발생하면 무조건 수고됩니다. WeakReference가 사라지는 시점이 GC의 실행 주기와 일치하며 이를 이용하여 짧은 주기에 자주 사용되는 객체를 캐시할 때 유용합니다.
아래 예제는 WeakReference, SoftReference 그리고 new 연산자를 이용한 Strong Reference 테스트를 진행한다. 실행 결과 Strong는 out of memory가 발생하여 finish가 출력되고, SoftReference, WeakReference는 GC에서 Memory를 수거하여 사용하고 있기 때문에 finish는 출력이 되지 않았다.
테스트를 돌려보면 알겠지만 SoftReference를 테스트했을 때 Window의 프로세스 점유율을 보면 엄청나게 올라감을 알 수 있었다.(소리가 위이이이이잉 나더라...)
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 55 56 57 58 59 60 61 62 | package com.ktko.init; import java.lang.ref.SoftReference; import java.lang.ref.WeakReference; import java.util.LinkedList; import java.util.List; // PhantomReference class BigData { private int[] array = new int[2500]; //10000byte, 10K } public class ReferenceTest { private List<WeakReference<BigData>> weakRefs = new LinkedList<>(); private List<SoftReference<BigData>> softRefs = new LinkedList<>(); private List<BigData> strongRefs = new LinkedList<>(); public void weakReferenceTest() { try { for (int i = 0; true; i++) { weakRefs.add(new WeakReference<BigData>(new BigData())); } } catch (OutOfMemoryError ofm) { // weak일 경우 out of memory 발생 하지 않는다. System.out.println("out of memory!"); } } public void softReferenceTest() { try { for (int i = 0; true; i++) { softRefs.add(new SoftReference<BigData>(new BigData())); } } catch (OutOfMemoryError ofm) { // weak일 경우 out of memory 발생 하지 않는다. System.out.println("out of memory!"); } } public void strongReferenceTest() { try { for (int i = 0; true; i++) { strongRefs.add(new BigData()); } } catch (OutOfMemoryError ofm) { // Strong일 경우 out of memory 발생 System.out.println("out of memory!"); } } public static void main(String[] args) { System.out.println("실행"); ReferenceTest test = new ReferenceTest2(); test.weakReferenceTest(); //test.softReferenceTest(); //test.strongReferenceTest(); System.out.println("종료"); } } |
서비스를 하는데 있어 메모리 관리는 정말로 중요하다. 근데 어떤 부분에서 어떻게 사용해야 할지는 개발자의 몫이다. 예를 들어 이미지를 관리할 때, 아니면 안드로이드에서 Activity를 관리할 때 등등이 있을 수 있다(라고 인터넷에서 찾아봤다.)
'Java 개발 이야기' 카테고리의 다른 글
자바 Clone에 대해서 (0) | 2018.10.04 |
---|---|
Oracle JDK와 Open JDK의 차이점 (0) | 2018.10.04 |
자바 박싱(boxing)과 언박싱(unboxing) (0) | 2018.09.27 |
자바 가변인자(Varargs)에 대해서 (0) | 2018.09.18 |
자바 제네릭(Generic) 개념과 사용법 1탄 (0) | 2018.09.12 |