-
Notifications
You must be signed in to change notification settings - Fork 2
Open
Labels
🐳 02 Objects2장 객체 생성과 파괴2장 객체 생성과 파괴
Description
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
Reactions are currently unavailable
Metadata
Metadata
Assignees
Labels
🐳 02 Objects2장 객체 생성과 파괴2장 객체 생성과 파괴