Q1. 자바의 메모리 구조에 대해 설명해주세요.
■ 스택(Stack)
각 스레드마다 하나씩 존재하는 공간입니다.
메서드를 호출할 때마다 ‘스택 프레임’이라는 작은 상자가 생기고,
그 안에 지역 변수, 인자, 리턴 값을 저장합니다.
메서드 실행이 끝나면 해당 프레임은 즉시 사라집니다 (후입선출 구조).
■ 힙(Heap)
모든 스레드가 공유하는 공간으로, new
로 생성한 모든 객체(Object)와 배열(Array)이 저장됩니다.
가비지 컬렉터(GC)가 주기적으로 더는 사용되지 않는 객체를 해제합니다.
힙은 효율적 GC를 위해 Young Generation과 Old Generation으로 나뉩니다.
💡 Young/Old Generation이란?
- Young Generation: 금방 생성되고 사라지는 객체들의 집합
- Old Generation: 여러 번 GC를 견뎌낸, 장기간 살아남은 객체들이 이동하는 영역
■ 메서드 영역(Method Area)
클래스별로 한 번 로드되어 공유되는 공간입니다.
클래스의 바이트코드 정보, static 변수, 그리고 런타임 상수 풀(Constant Pool)이 저장됩니다.
💡 런타임 상수 풀이란?
변경되지 않는 상수(문자열 리터럴, 클래스·메서드 참조 정보 등)를 저장하는 특별한 공간입니다.
자바의 메모리 구조 다이어그램
Q2. 자바에서 메모리 누수(Memory Leak)가 발생하는 원인과 방지 방법은 무엇인가요?
원인: Static 필드에 객체 유지
static 변수는 애플리케이션 종료 전까지 살아 있어서, 그 안에 담긴 객체는 절대 GC 대상이 되지 않습니다.
해결책: 더 이상 필요 없는 객체는 null
처리하거나, static 대신 인스턴스 필드로 전환해야 합니다.
원인: 리소스(파일·소켓 등) 미반환
InputStream, DB Connection 등을 닫지 않으면 내부 버퍼나 소켓이 해제되지 않아 메모리 누수가 발생합니다.
해결책: try-with-resources
를 사용하거나, finally
블록에서 반드시 close()
를 호출해야 합니다.
원인: 잘못 구현된 equals()/hashCode()
HashMap, HashSet 등에 키나 값이 중복으로 계속 쌓이면, 오래된 객체가 메모리에 남아 있습니다.
해결책: equals()
와 hashCode()
를 일관성 있게 오버라이드하여 중복 참조를 방지해야 합니다.
원인: 비static 내부 클래스 & 익명 클래스
비static 내부 클래스는 외부 인스턴스를 암묵적으로 참조하여, 해제되지 않으면 외부 객체도 메모리에 남습니다.
해결책: 가능하면 static
내부 클래스를 사용하거나, 람다 표현식으로 대체해야 합니다.
원인: 캐시 미정리
Map이나 컬렉션에 담긴 객체를 주기적으로 제거하지 않으면, 사용 후에도 계속 메모리를 차지합니다.
해결책: WeakHashMap
같은 약한 참조를 사용하거나, 만료 정책에 따라 캐시를 정리하는 로직을 추가해야 합니다.
원인: 리스너/콜백 미해제
이벤트 리스너나 콜백 함수가 등록된 채로 해제되지 않으면, 해당 객체가 계속 참조되어 메모리에 남습니다.
해결책: 더 이상 사용하지 않을 때 removeListener()
등으로 반드시 등록을 해제해야 합니다.
'CS 공부 > Java' 카테고리의 다른 글
[기술 면접] Garbage Collection 이해하기 (3) | 2025.06.02 |
---|---|
[기술 면접]Java Generic 이해하기2 (0) | 2025.06.02 |
[기술 면접]Java Generic 이해하기1 (0) | 2025.06.02 |