앱 개발이 마무리 단계에 들어서서, 테스트하면서 부딪히는 문제가 바로 MemoryLeak입니다.

MemoryLeak(메모리 누수)가 나는데는 여러가지 문제가 있습니다만.

해결책으로 종종 제시되는 것이 WeakReference(약한 참조)인데요.

이것은 StrongReference(강한참조)와 어떻게 다르고, 어떻게 구현하는 것일까요?

오늘은 그 방법에 정리해 보겠습니다.



1. WeakReference vs StrongReference


WeakReference와 StrongReference에 대해서 간단히 정리해 보도록 하겠습니다.

(SoftReference나 Phantom도 있지만 이 부분은 다음에 글로 정리해 보도록 하겠습니다.)


우리말로 하면 약한 참조 vs 강한 참조가 되는데요.

무언가가 약하고 강하다는 것인데, 어떤 면에서 그러한 것일까요?


쉽게 생각해보면 참조가 강하게 되어있는냐, 않느냐의 뜻인데요.

무엇때문에 그것을 나누는 것일까 생각해보면,

그것은 메모리 관리와 연관되어 있습니다.


보통 많이 사용하는 객체 생성방법인, new()메소드를 사용해서 생성하는 StrongReference(강한 참조)와 WeakReference클래스를 사용하는 약한 참조는,

Garbage Collector(이하, GC 라고 하겠습니다.)에 의해서 메모리상에서 회수되는지의 기준이 다릅니다.


GC가 메모리를 정리할 대상인지 판단하기위해서 reachability라는 기준을 가지고 있는데요.

StrongReference의 경우 reachability에 있어서 기준은,

가장 먼저 참조되어지는 root객체로부터 사슬이 계속 연결되어 있는가의 여부입니다.

이 사슬이 끊어져 있다면, unreachable로 보고, GC의 메모리 회수대상이 되는 것인데요.


반면에, 약한 참조의 경우는 명확하게 GC에 의한 메모리상의 회수대상이 되어집니다.


메모리릭의 대표적 예인, StrongReference에 의해서 View가 Activity를 참조하는 경우를 생각해보겠습니다.

Activity가 View에 의해서 참조되어 있기 때문에,

ActivityLifeCycle을 지나도, 메모리상에서 정리되지 못하고 MemoryLeak(메모리 누수)을 발생시키게 되는 거죠.


하지만, WeakReference를 사용하여 구현하였다면, 
GC의 메모리 회수 대상이 될 뿐더러, WeakReference객체에 대한 참조를 null값으로 해주므로,
MemoryLeak(메모리 누수)가 일어나지 않도록 미연에 방지할 수 있는 것이죠.

그럼 이제, 실제로 코드를 보면서 구현에 대해서 알아보도록 하겠습니다.




2. WeakReference 구현


WeakReference를 구현하는 일은 그리 복잡하지 않습니다.

java에서는 lang패키지의 WeakReference 클래스를 사용하면 되는데요.

참조할 객체를 캡슐화해서 객체로 제공해 줍니다.

아래의 코드를 보면 좀 더 이해하기 쉬울 것은데요.




보신것처럼 뭔가 독특한 것 같지만, 단순히 new()메소드로 생성해서, wrapping한 객체입니다.

이렇게 생성한 객체는 wrap한 mWeak객체에 get()메소드로 얻어올 수 있습니다.


얻어온 mStudent객체에 null을 대입해주면 Student객체에 대한 접근은 WeakReference인 mWeak를 통해서만 가능하게 됩니다.

이렇게 WeakReference에 의해서만 접근할 수 있는상태가 됬을 때,

reachability가 약하다고 할 수 있는데요.


이 상태가 되면, GC동작시에 WeakReference객체에 대한 참조를 null값으로 해주기 때문에,

GC에 의해서 메모리상에서 정리되는 대상이 될수 있는 것이죠.

(참고로 GC가 언제 동작하는 지를 저희가 알수는 없습니다.)

메모리 릭이 날 수 없도록, 좀 더 명확하게 해주는 것이라고 할 수도 있겠네요.

+ Recent posts