반응형

안녕하세요.

WeakReference에 대해서 간략하게 알아보고 예제를 살펴보도록 하겠습니다.

WeakReference는 클래스입니다 :) 그리고 GC(Garbage Collector)와 밀접한 연관성이 있습니다.

GC는 개발자의 영역이 아닌데 WeakReference을 사용함으로써 GC에게 어느정도 개입을 할 수가 있습니다.

GC는 불필요한 객체(참조하고 있지 않는)들을 힙 메모리에서 제거를 해줍니다. 특정 객체가 Weak Reference(약한 참조) 상태가 되면 GC는 이 객체를 제거를 합니다. 빠르게 객체를 제거함으로써 잠깐 사용하고 제거를 할 수 있는 것이죠.

new를 사용하여 객체를 만들때는 강한 Reference가 적용이 되는데, WeakReference를 사용하여 객체를 만들 때는 약한 Reference가 적용이 됩니다.

 

예제를 살펴보도록 하겠습니다.

    @Test
    public void weakReferenceStackManipulation() {
        final WeakReferenceStack<ValueContainer> stack = new WeakReferenceStack<>();

        final ValueContainer expected = new ValueContainer("Value for the stack");
        stack.push(new ValueContainer("Value for the stack"));

        ValueContainer peekedValue = stack.peek();
        assertEquals(expected, peekedValue);
        assertEquals(expected, stack.peek());
        peekedValue = null;
        System.gc();
        assertNull("Fail", stack.peek());
    }

위의 예제는 stack을 WeakReference형으로 선언하였습니다. WeakReference은 ValueContainer을 래퍼해줍니다.

ValueContainer 객체를 생성하고, 이 객체를 stack에 집어넣었습니다.

그리고 두 값을 비교하면 같은 값이 됩니다.

이때 peekedValue는 WeakReference 형으로 선언된 값을 참조하기 때문에, peekedValue 값에 null을 대입하면 WeakReference 형으로 선언된 객체는 GC가 동작될 때 제거됩니다. 그렇기 때문에 stack 값을 갖고 오면 stack에 값이 있을 것으로 생각이 되지만 GC에 의해서 이미 제거되어 null이 됩니다.

GC가 동작하지 않았더라면(System.gc() 주석 처리), GC가 동작하기 전까지는 null값이 아니기 때문에 마지막 테스트는 실패하게 됩니다.

LRU 캐시처럼 객체를 짧게 사용하는 곳에서는 WeakReference가 유용할 수 있겠습니다.

감사합니다.

반응형

+ Recent posts