728x90
C, C++ 과 같이 메모리를 직접 관리해야하는 언어와 다르게 자바는 GC가 메모리 관리를 해준다.
하지만 메모리 관리에 신경쓰지 않아도 되는 것은 아니다.
- 메모리 누수가 일어나는 코드
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];
// }
private void ensureCapacity() {
if (elements.length == size)
elements = Arrays.copyOf(elements, 2 * size + 1);
}
// 코드 7-2 제대로 구현한 pop 메서드 (37쪽)
public Object pop() {
if (size == 0)
throw new EmptyStackException();
Object result = elements[--size];
// elements[size] = null; // 다 쓴 참조 해제
return result;
}
public static void main(String[] args) {
Stack stack = new Stack();
for (String arg : args)
stack.push(arg);
while (true)
System.err.println(stack.pop());
}
}
스택에서 elements에 오브젝트가 쌓이기만 하고 빠지지 않는다.
이 스택을 사용하는 프로그램을 오래 실행하다 보면 점차 가비지 컬렉션 활동과 메모리 사용량이 늘어나 결국 성능이 저하 될 것이다.
pop 메서드의 참조 해제를 적용하면 GC의 대상이 되어 메모리가 정리된다.
스택, 캐시 등 개발자가 메모리를 관리해야 할 때는 이러한 메모리 누수에 주의해야 한다.
캐시 역시 메모리 누수를 일으키는 주범이다.
객체 참조를 캐시에 넣고 나서 , 이 사실을 잊은 채 객체를 다 쓴 뒤로도 한참을 그냥 놔둘 수 있다.
해법은 여러가지다. weakHashMap과 같은 약한 참조를 이용해 캐시를 만들거나, 스케쥴러를 이용해 사용되지 않는 객체를 해제해주는
방법 등을 사용 할 수 있겠다.
728x90
'JAVA > 이펙티브 자바' 카테고리의 다른 글
9.try-finally보다는 try-with-resources를 사용하라 (0) | 2023.06.20 |
---|---|
8. finalizer와 cleaner 사용을 피하라 (0) | 2023.06.20 |
6. 불필요한 객체 생성을 피하라 (0) | 2023.06.14 |
5. 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라 (0) | 2023.06.11 |
4. 인스턴스화를 막으려면 private 생성자를 사용하라 (0) | 2023.06.10 |