프로그래밍자바 개발자

자바에서 메모리 자동 관리 메커니즘(가비지 컬렉터)은 어떻게 작동하나요?

Hintsage AI 어시스턴트로 면접 통과

답변

자바에서 메모리는 자동 가비지 수집기(Garbage Collector, GC)를 통해 관리됩니다. JVM은 메모리 내의 객체를 스스로 추적합니다: 만약 객체에 대한 참조가 더 이상 없다면, 해당 객체는 도달 불가능하게 되며 삭제될 수 있습니다.

GC는 Mark, Sweep 및 때때로 Compact와 같은 여러 단계로 구성됩니다. Mark 단계에서 GC 루트에서 접근 가능한 객체들은 살아있는 것으로 표시됩니다. 그 후 Sweep이 시작됩니다: 사용되지 않는 객체가 삭제됩니다. 가끔 Compact이 수행되어 메모리 단편화를 방지합니다.

다양한 GC 유형이 있습니다: Serial, Parallel, CMS, G1. 이는 애플리케이션의 부하 유형에 따라 선택해야 합니다.

메모리 누수 상황의 코드 예시:
List<byte[]> dataList = new ArrayList<>(); while(true) { dataList.add(new byte[1024*1024]); // 객체는 여전히 도달 가능합니다 }

이 예시에서 객체는 결코 도달 불가능해지지 않으며, GC는 이를 삭제하지 않아서 OutOfMemoryError가 발생합니다.

미끼 질문

객체에 더 이상 참조가 없는 경우, 그의 최종자(finalizer)(finalize())가 호출되는 것은 언제 보장되나요?

답변: finalize() 메서드 호출은 전혀 보장되지 않습니다! 이 메서드는 한 번도 호출되지 않거나 지연되어 호출될 수 있습니다. 자원 해제를 위해 finalize()에 의존할 수 없습니다.

@Override protected void finalize() throws Throwable { // 작동하지 않을 수 있습니다! }

주제에 대한 세부사항을 몰라서 발생한 실제 오류 사례들


이야기

대형 전자상거래 시스템에서 개발자들은 finalize() 메서드를 이용해 임시 파일 정리를 자동화하려고 했으나, 이 메서드의 드문 호출로 인해 캐시가 임시 파일로 가득 차서 디스크 부족과 다운타임이 발생했습니다.


이야기

고부하 REST API에서 큰 객체에 대한 내부 참조 캐시가 실수로 저장되어 메모리 해제를 방해했습니다. 애플리케이션이 OutOfMemoryError로 종료된 후 분석 결과, 캐싱 메서드의 오류가 밝혀졌습니다.


이야기

최종자는 네트워크 연결 해제를 위해 사용되었으며, 이를 "신뢰할 수 있는 방법"으로 간주했습니다. 이로 인해 연결이 시스템 내에서 불확실하게 오랫동안 남아 있어 잠금 및 연결 풀 고갈을 초래했습니다.