자바는 기본적으로 C나 C++에 비해 다 쓴 객체에 대한 메모리 공간에 대한 고민이 적다.
이는 자바에는 가비지 컬렉터가 있기 때문에 다 쓴 객체에 대해 알아서 제거를 해주기 때문이다.
하지만 가바지 컬렉터가 찾지 못하는 다 쓴 객체가 존재하고 이는 메모리 누수를 발생시킨다.
메모리 누수
- 메모리에 처리되지 못한 객체가 쌓이게 되고 성능저하의 원인이 된다.
- 심한 경우, 디스크 페이징이나 OutOfMemoryError까지 발생하게 된다.
메모리 누수 1 : 스택과 같이 배열에 객체를 담는 경우, 데이터를 담았다 삭제할 때 , 실제 객체가 삭제되지 않음
- 스택이 여전히 다 쓴 객체들을 참조하기 때문이다.
- 이는, 내부적으로 객체를 pop 처리하면 삭제하는 것이 아닌 가리키는 인덱스만 변경하는 구조이기 때문임.
해결책 : 참조해제
(Null 처리)
- pop시에 해당 객체에 대해 null처리를 해주자, 이 후, nullpointexeption 발생시킴으로 해결
-> 하지만 지나친 null 처리는 코드를 더럽힌다.
-> 유효 범위 밖으로 객체를 밀어버리는것이 가장 좋은 방식이고 null 처리하는 것은 예외적인 경우에 사용하자.
(Null 처리를 하는 경우)
- 스택과 같이 자기 메모리를 직접 관리하는 경우에 사용한다. (= 배열에 담는 경우 등에 사용한다.)
메모리 누수 2 : 캐시
- 캐시 역시 메모리 누수의 주범이다.
- 예를들어, HashMap을 캐시로 사용하는 경우, 기존에 사용하던 key를 null처리하더라도 엔트리는 살아있다.
- 이러한 경우 WeakHashMap을 사용한다면, 키가 살아있는 동안만 엔트리가 살아있게 도와준다.
(키를 null처리시 가비지 컬렉터가 수거해간다.)
엔트리 : 키-값 구조의 형태
메모리 누수 : 콜백, 리스너
- 클라이언트는 콜백을 등록만하고 명확히 해지하지 않는다.
- 이렇게 되면 콜백은 쌓여갈 것이다.
- 콜백을 약한 참조로 저장하면 가비지 컬렉터가 수거해갈 것이다.
- 예를들어, WeakHashMap의 키로 저장한다.
결론 : 자바는 가비지 컬렉터가 다 쓴 객체를 기본적으로 수거한다. 하지만 그러한 객체를 못찾는 경우가 존재하고 이를 미리 알고 대비하자.
코드 정리
https://github.com/mokjaemin/EffectiveJAVA
'Language > Java Plus' 카테고리의 다른 글
Effective JAVA - Item9 : try-finally 보다는 try-with-resources를 사용하라. (0) | 2023.09.13 |
---|---|
Effective JAVA - Item8 : finalizer와 cleaner 사용을 피하라 (0) | 2023.09.13 |
Effective JAVA - Item6 : 불필요한 객체 생성을 피하라. (0) | 2023.09.12 |
Effective JAVA - Item5 : 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라. (0) | 2023.06.22 |
Effective JAVA - Item4 : 인스턴스화를 막으려거든 private 생성자를 사용하라. (0) | 2023.06.10 |