서론
프로그래밍을 하다 보면 메모리 관리는 필수적인 작업이다. 프로그램이 실행되는 동안 새로운 객체를 생성하고 데이터를 저장하기 위해서는 메모리 공간이 지속적으로 필요하기 때문이다. 하지만 일정 시간이 지나면서 더 이상 사용되지 않는, 불필요한 메모리 공간들이 발생하게 된다. 이렇게 남아있는 사용되지 않는 메모리를 '가비지(garbage)'라고 부른다.
과거에는 프로그래머가 직접 이러한 가비지 메모리를 수동으로 해제해야 했다. 하지만 수동 메모리 관리에는 메모리 해제를 잊어버리면 메모리 누수(memory leak)가 발생하고, 이는 시스템 성능 저하와 심지어 프로그램 다운까지 초래하는 등의 문제점이 있다.
가비지 컬렉터(Garbage Collector)
수동 메모리 관리의 어려움을 해결하기 위해 등장한 것이 바로 '가비지 컬렉터(Garbage Collector)'다. 가비지 컬렉터는 메모리 관리 방법 중의 하나로 프로그램이 실행되는 동안 더 이상 사용되지 않는 메모리 영역을 자동으로 탐지하고 해제해주는 역할을 한다. 이를 통해 개발자는 메모리 관리에 대한 부담에서 벗어나 애플리케이션 로직에 전념할 수 있게 되었다.
Java에서의 Garbage Collector
자바에서는 가비지 컬렉터(Garbage Collector)가 Java 가상 머신(JVM) 내부의 실행 엔진으로 탑재되어 있다.
자바 가상 머신의 가비지 컬렉터가 작동하는 메모리 영역은 Heap 메모리 영역이다.
자바 가상 머신은 가비지 컬렉터를 이용하여 Heap 메모리 영역에서 더는 사용하지 않는 메모리를 자동으로 회수해 준다.
[예시]
for (int i = 0; i < 10000; i++) {
NewObject obj = new NewObject();
obj.doSomething();
}
위의 코드 같은 경우 루프문 안에서 생성한 객체들은 루프문이 끝나면 더 이상 사용할 일이 없어진다. 가비지 컬렉션은 이런 객체들을 주기적으로 비워준다.
가비지 컬렉션의 장단점
장점
- 메모리 관리를 자동화하여 개발자의 부담을 줄인다.
- 메모리 누수 및 중복 해제 등의 메모리 관련 버그를 방지할 수 있다.
- 메모리 사용량을 최적화하고 애플리케이션의 전체 성능을 높일 수 있다.
단점
- 가비지 컬렉션 자체에 오버헤드가 발생하며 애플리케이션 중지 시간이 길어질 수 있다.
- 가비지 수집 시점을 정확하게 예측하기 어려워 실시간 시스템에는 적합하지 않을 수 있다.
📌 STW(Stop The World)
GC를 수행하기 위해 JVM이 프로그림 실행을 멈추는 현상을 의미
GC가 작동하는 동안 GC관련 Thread를 제외한 모든 Thread는 멈추게 되어 서비스 이용에 차질이 생길 수 있다.
이로 인해 GC가 너무 자주 실행되면 소프트 웨어 성능 하락의 문제가 되기도 한다.
가비지 컬렉션 대상
가비지인지 판단하기 위해 도달성(도달능력,Reachability)이라는 개념을 사용한다.
📌 도달성
- Reachable: 객체에 레퍼런스(참조)가 있는 상태
- Unreachable: 객체에 유효한 레퍼런스(참조)가 없는 상태
객체같은 경우 실질적인 메모리는 Heap영역에 저장되고 Method Area나 Stack Area에서 해당 객체의 주소만 참조하는 형식으로 된다.
만약 참조하는 변수가 삭제된다면 Heap영역에 저장되었던 객체는 Unreachable 상태가 되어 가비지 컬렉션의 대상이 된다.
Mark And Sweep
Mark-Sweep은 다양한 GC에서 사용되는 내부 알고리즘이다. Unreachable한 객체를 청소하는 방법이다.
1. 가비지 컬렉션이 될 대상 객체를 식별(Mark)하고 제거한다.
2. 객체가 제거되어 흩어져 있는 메모리를 메모리 영역의 앞에서부터 채워나가는 작업(Compaction)을 수행한다.
요약
가비지 콜렉션은 메모리 관리를 자동화하여 개발자의 부담을 줄이고 메모리 관련 버그를 방지하는 중요한 역할을 한다.
참고: Inpa님 블로그
'language > JAVA' 카테고리의 다른 글
[JAVA] 배열, 스트림 활용 (0) | 2024.06.22 |
---|---|
[JAVA] 제네릭(Generic), 제네릭 클래스, 제네릭 메서드, 와일드카드 (0) | 2024.06.22 |
[JAVA][Exception] Map Duplicate key (0) | 2024.06.15 |
[JAVA] Overriding 과 Overloading 의 차이점 (0) | 2024.02.19 |
[JAVA] Comparator, Comparable로 배열과 List를 정렬하기 (0) | 2024.02.16 |