본문 바로가기

Language/Java Plus

Effective JAVA - Item7 : 다 쓴 객체 참조를 해제하라

 

 

 

자바는 기본적으로 C나 C++에 비해 다 쓴 객체에 대한 메모리 공간에 대한 고민이 적다.

이는 자바에는 가비지 컬렉터가 있기 때문에 다 쓴 객체에 대해 알아서 제거를 해주기 때문이다.

하지만 가바지 컬렉터가 찾지 못하는 다 쓴 객체가 존재하고 이는 메모리 누수를 발생시킨다.

 

 

 

메모리 누수

- 메모리에 처리되지 못한 객체가 쌓이게 되고 성능저하의 원인이 된다.

- 심한 경우, 디스크 페이징이나 OutOfMemoryError까지 발생하게 된다.

 

 

 

메모리 누수 1 : 스택과 같이 배열에 객체를 담는 경우, 데이터를 담았다 삭제할 때 , 실제 객체가 삭제되지 않음

- 스택이 여전히 다 쓴 객체들을 참조하기 때문이다.

- 이는, 내부적으로 객체를 pop 처리하면 삭제하는 것이 아닌 가리키는 인덱스만 변경하는 구조이기 때문임.

 

해결책 : 참조해제

 

(Null 처리)

- pop시에 해당 객체에 대해 null처리를 해주자, 이 후, nullpointexeption 발생시킴으로 해결

-> 하지만 지나친 null 처리는 코드를 더럽힌다.

-> 유효 범위 밖으로 객체를 밀어버리는것이 가장 좋은 방식이고 null 처리하는 것은 예외적인 경우에 사용하자.

 

(Null 처리를 하는 경우)

- 스택과 같이 자기 메모리를 직접 관리하는 경우에 사용한다. (= 배열에 담는 경우 등에 사용한다.)

 

 

 

메모리 누수 2 : 캐시

- 캐시 역시 메모리 누수의 주범이다.

- 예를들어, HashMap을 캐시로 사용하는 경우, 기존에 사용하던 key를 null처리하더라도 엔트리는 살아있다.

- 이러한 경우 WeakHashMap을 사용한다면, 키가 살아있는 동안만 엔트리가 살아있게 도와준다.

(키를 null처리시 가비지 컬렉터가 수거해간다.)

 

엔트리 : 키-값 구조의 형태

 

 

 

메모리 누수 : 콜백, 리스너

- 클라이언트는 콜백을 등록만하고 명확히 해지하지 않는다.

- 이렇게 되면 콜백은 쌓여갈 것이다.

- 콜백을 약한 참조로 저장하면 가비지 컬렉터가 수거해갈 것이다.

- 예를들어, WeakHashMap의 키로 저장한다.

 

 

 

결론 : 자바는 가비지 컬렉터가 다 쓴 객체를 기본적으로 수거한다. 하지만 그러한 객체를 못찾는 경우가 존재하고 이를 미리 알고 대비하자.

 

 

코드 정리

https://github.com/mokjaemin/EffectiveJAVA

 

GitHub - mokjaemin/EffectiveJAVA: Study Files Of Effective JAVA

Study Files Of Effective JAVA. Contribute to mokjaemin/EffectiveJAVA development by creating an account on GitHub.

github.com