brunch

You can make anything
by writing

C.S.Lewis

by myner Nov 24. 2019

Java Reference와 GC

나를 다시 붙잡는 심정으로, 마음을 다잡는 심정으로 - 브런치 2

부제에서도 보이지만 당분간 쓸 글은 '나를 다시 붙잡는 심정으로, 마음을 다잡는 심정으로' 시리즈가 될 듯싶다. 기본을 돌아보고 싶을때, 마음을 다잡고 싶을때 가볍게 보는 그런 기술 브런치를 작성해 나가려고 한다.



Java의 가비지 컬렉터(Garbage Collector)은 크게 다음 2가지 작업을 수행한다고 볼 수 있습니다. 

    1. 힙(heap) 내의 객체 중에서 가비지(garbage)를 찾아낸다.

    2. 찾아낸 가비지를 처리해서 힙의 메모리를 회수한다.


Java GC는 객체가 가비지인지 판별하기 위해서 reachability라는 개념을 사용한다. 어떤 객체에 유효한 참조가 있으면 'reachable'로, 없으면 'unreachable'로 구별하고, unreachable 객체를 가비지로 간주해 GC를 수행한다. 


Soft, Weak, Phantom 

java.lang.ref는 soft reference와 weak reference, phantom reference를 클래스 형태로 제공한다.


사실 이 부분은 많은 곳에서도 찾을 수 있고 본인이 이미 이해하고 있다면 넘어가도 좋다. 실제로 WeakReference 혹은 이를 이용한 WeakHashMap는 내부캐시 구현에 많이 사용되고 있어서 많이들 겪어보았을 것이다. 필자는 phantom에 대해 기록을 남겨 보려한다.


어떤 객체에 대해 GC 여부를 판별하는 작업은 이 객체의 reachability를 strongly, softly, weakly 순서로 먼저 판별하고, 모두 아니면 phantomly reachable 여부를 판별하기 전에 파이널라이즈를 진행한다. 그리고 대상 객체를 참조하는 PhantomReference가 있다면 phantomly reachable로 간주하여 PhantomReference를 ReferenceQueue에 넣고 파이널라이즈 이후 작업을 애플리케이션이 수행하게 하고 메모리 회수는 지연시킨다.


    1. soft references

    2. weak references

    3. 파이널라이즈

    4. phantom references

    5. 메모리 회수


PhatomReference는 항상 ReferenceQueue를 필요로 한다. 그리고 PhantomReference의 get() 메서드는 SoftReference, WeakReference와 달리 항상 null을 반환한다. 따라서 한 번 phantomly reachable로 판명된 객체는 더 이상 사용될 수 없게 된다. 그리고 phantomly reachable로 판명된 객체에 대한 참조를 GC가 자동으로 null로 설정하지 않으므로, 후처리 작업 후에 사용자 코드에서 명시적으로 clear() 메서드를 실행하여 null로 설정해야 메모리 회수가 진행된다.


이와 같이, PhantomReference를 사용하면 어떤 객체가 파이널라이즈된 이후에 할당된 메모리가 회수되는 시점에 사용자 코드가 관여할 수 있게 된다. 파이널라이즈 이후에 처리해야 하는 리소스 정리 등의 작업이 있다면 유용하게 사용할 수 있다. 


Realm 의 NativeObjectReference(https://github.com/realm/realm-java/blob/0e1464114782f88165309bd0d73d13a8fde72ab7/realm/realm-library/src/main/java/io/realm/internal/NativeObjectReference.java)를 보면 PhantomReference의 사용법을 엿볼수 있다.





출처 

https://d2.naver.com/helloworld/329631

브런치는 최신 브라우저에 최적화 되어있습니다. IE chrome safari