Skip to content

Item 7. 다 쓴 객체 참조를 해제하라 #8

@byunghyunkim0

Description

@byunghyunkim0

Chapter : 2. 객체 생성과 파괴

Item : 7. 다 쓴 객체 참조를 해제하라

Assignee : byunghyunkim0


🍑 서론

가비지 컬렉터를 갖춘 언어라도 메모리 관리에 대해서 생각을 해야한다.

🍑 본론

가비지 컬렉션에서 메모리 누수 발생

public class Stack {
    private Object[] elements;
    private int size = 0;
    private static final int DEFAULT_INITIAL_CAPACITY = 16;

    public Stack() {
        elements = new Object[DEFAULT_INITIAL_CAPACITY];
    }

    public void push(Object e) {
        ensureCapacity();
        elements[size++] = e;
    }

    public Object pop() {
        if (size == 0)
            throw new EmptyStackException();

        return elements[--size];
    }

    // 해법
    public Object pop(){
        if(size == 0){
            throw new EmptyStackException();
        }
        Object result = elements[--size];
        elements[size] = null;
        return result;
    }

    /**
     * 원소를 위한 공간을 적어도 하나 이상 확보한다.
     * 배열 크기를 늘려야 할 때마다 대략 두 배씩 늘린다.
     */
    private void ensureCapacity() {
        if (elements.length == size)
            elements = Arrays.copyOf(elements, 2 * size + 1);
    }
}
  • 스택에서 꺼내진 객체는 더 이상 사용하지 않더라도 GC가 회수 하지 않는다.
  • 이 스택이 객체들의 다 쓴 참조를 계속 갖고 있게 되고, 메모리 사용량이 늘어나 성능이 저하된다.

메모리 누수를 일으키는 주범

1. 자기 메모리를 직접 관리하는 클래스(stack)

  • 다 사용한 원소는 즉시 null 처리

2. 캐시 메모리

  • 객체 참조를 캐시에 넣어놓고 다 쓴 뒤에도 놔두면 메모리 누수가 발생
    • java.util.WeakHashMap을 사용해서 캐시를 만든다. (다 쓴 엔트리는 즉시 자동으로 제거)
import java.util.WeakHashMap;

public class WeakHashMapTest {

    public static void main(String[] args) {
        WeakHashMap<Integer, String> map = new WeakHashMap<>();

        Integer key1 = 1000;
        Integer key2 = 2000;

        map.put(key1, "test a");
        map.put(key2, "test b");

        key1 = null;

        System.gc();  //강제 Garbage Collection

        map.entrySet().forEach(el -> System.out.println(el));

    }
}

3. 리스너 or 콜백

  • 클라이언트가 콜백을 등록만하고 해지하지 않는다면, 계속 쌓임
    • 콜백을 약한 참조로 저장하면 해결된다. ex) WeakHashMap에 키로 저장

🍑 결론


Referenced by

Metadata

Metadata

Assignees

Labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions