Garbage Collector
• 자바는 Garbage Collector 를 갖춘 언어
• 메모리를 직접 관리해야하는 C/C++과 달리, 다 쓴 객체를 알아서 회수해준다.
• JVM에서 GC의 스케줄링을 담당
• 객체는 힙 영역에 저장되고 스택 영역에 이를 가리키는 주소값이 저장되는데 참조되지 않는
(자신을 가리키는 포인터가 없는, unreachable) 객체를 메모리에서 제거한다.
Person person = new Person();
person.setName("Mang");
// garbage 발생
person = new Person();
person.setName("MangKyu");
메모리 누수
• 컴퓨터 프로그램이 필요하지 않은 메모리를 계속 점유하고 있는 현상
• Old 영역에 계속 누적된 객체로 인해 Major GC가 빈번하게 발생하게 되면서 성능 저하를 불러온다.
• 디스크 페이징이나 OutOfMemoryError 를 일으켜 프로그램이 종료될 수도 있다.
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;
}
해결 방법(1) : null 처리
• 해당 참조를 다 썼을 때 null 처리(참조 해제)를 해주는 방법
• 사용이 끝난 참조에 실수로 접근하는 경우 NullPointerException을 내주는 효과도 있다.
• 예외적인 경우에만 사용하자 : 자기 메모리를 직접 관리하는 클래스의 경우
◦ 그 외에는 프로그램을 필요 이상으로 지저분하게 만들 뿐
해결방법(2) : 참조를 담은 변수를 유효 범위(scope) 밖으로 밀어내기
• 변수의 범위를 최소가 되게 정의하자
for(int i=0;i<10;i++){...} // i 의 범위를 10 미만으로 제한했다.
기타 메모리 누수가 발생하는 상황 및 해결책
1) 캐시(cache)에 객체를 넣어두고 잊어버리는 경우
• java.lang.ref 패키지의 WeakReference 클래스를 사용하는 방법
WeakReference<Integer> A = new WeakReference<Integer>(new Integer(1));
Integer B = A.get() // B = 1
B = null;
C = A.get();
// Integer 객체를 가리키는 참조가 WeakReference 객체 A 뿐 : 1은 GC 대상
• WeakHashMap 을 사용하는 방법
◦ 일반적인 HashMap의 경우 일단 Map안에 Key와 Value가 put되면 사용여부와 관계없이 해당 내용은 삭제되지 않는다.
◦ WeakReference를 이용해 HashMap의 Key를 구현하는 WeakHashMap을 이용하자.
• 백그라운드 스레드(ScheduledThreadPoolExecutor)를 활용하는 방법
◦ 어떤 작업을 일정 시간 지연 후에 수행하거나, 일정 시간 간격으로 주기적으로 실행해야 할 때 사용
• 캐시에 새 엔트리를 추가할 때 부수 작업을 수행하는 방법
◦ LinkedHashMap 을 사용하는 방법 (removeEldestEntry)(10)
- 일정 사이즈가 차면 가장 오래된 값을 지우고, 그 자리에 방금 들어온 값을 대체 한다.
2) 콜백(callback) / 리스너(listener)
• 피호출자(Callee)가 호출자(Caller)를 다시 호출하는 함수 : 콜백함수
◦ 비동기적 처리를 하기 위한 디자인 패턴의 한 종류
• 콜백을 등록만 하고 명확히 해지하지 않는 경우 메모리 누수가 발생한다
• 콜백을 약한 참조로 저장하면 가비지 컬렉터가 즉시 수거해간다.
◦ WeakHashMap 에 키로 저장하는 방법
참고자료
'Java' 카테고리의 다른 글
[Effective Java] ITEM14 : Comparable을 구현할지 고려하라 (0) | 2022.07.30 |
---|---|
[Effective Java] ITEM9 : try-finally 보다는 try-with-resources를 사용하라 (0) | 2022.07.24 |
[Effective Java] ITEM5 : 자원을 직접 명시하지 말고 의존 객체 주입을 사용하라 (0) | 2022.07.24 |
[Effective Java] ITEM3 : private 생성자 혹은 enum 타입으로 싱글톤임을 보증하라 (0) | 2022.07.23 |
[JAVA] GC(Garbage Collection) 톺아보기 (0) | 2022.07.10 |