1. JVM의 메모리 영역에는 어떤 부분들이 있고 어떤 데이터들이 저장되는지

1. Heap 영역
저장되는 데이터
- 클래스 인스턴스
- final class는 Method 영역에 저장…
- 배열
- 신규 객체
- 즉,
**new** 를 통해 생성된 객체가 저장되는 영역
구조
- Young Generation
- Eden
- Survivor 1
- Survivor 2
- Old Generation
- Permanent Generation
- JDK 8부터 Metaspace로 변경(더 이상 Heap에 없음)
- JDK 8부터 Native Method Stack 영역으로 넘어감
- Perm 영역은 기존에 상수와 static 변수, 런타임 중에 읽은 클래스와 메소드의 메타데이터를 저장
- 동적으로 클래스들이 로드되고 Static 변수나 상수가 Perm영역에 쌓이게 되면서 OOM이 자주 발생 → 그래서 Heap에서 Native Memory로
특징
- 모든 thread들이 공유하는 데이터들이 저장되는 메모리
- JVM 시작될 때 생성되는 영역
- GC의 대상이 되는 영역
2. Method 영역
저장되는 데이터
- Constant Pool
- 실제 상수 값과 실행시 변하게 되는 필드 참조 정보도 포함
- static 변수의 주소값
public static Person p = new Person();
new Person()에 의해 생성된 Person 객체는 힙(heap) 메모리에 저장
p는 메서드 영역(Method Area) 또는 클래스가 로드되는 메모리 영역에 저장
**p 자체는 메서드 영역에 저장된다**
**p의 값은 heap에 생성된 Person 객체의 주소값**
- 클래스 정보 : 클래스 로더에 의해 처음 메모리에 올라온 클래스 정보
특징
- 모든 thread들이 공유하는 데이터들이 저장되는 메모리
- 클래스가 JVM에 로딩될 때, 이 method 영역에 클래스 정보가 생성
- 프로그램이 종료될 때까지 메모리에 남아있음 → Memory leak 발생 가능
3. JVM Stack 영역
저장되는 데이터
동작 방식
- 각 thread 별로 stack 영역 가짐
- 메서드 호출될 때마다, 이 메서드를 위한 stack frame이 생성
- 메서드 종료되면, 해당 frame은 stack에서 제거
- 스택 크기 최대치 넘기면 StackOverflowError 발생
4. PC 레지스터 영역
동작 방식
- 각 thread 마다 하나씩 존재
- 현재 실행 중인 JVM instruction 주소를 저장
- thread가 명령 실행할 때마다 PC 레지스터는 현재 실행 중인 pc 값 주고 다음 instruction으로 pc값 업데이트
5. Native Method Stack 영역
- 자바 코드에서 네이티브 코드를 호출할 때 사용
- 자바 이외의 언어(C, C++, 어셈블리 등)로 작성된 네이티브 코드를 실행할 때 사용되는 메모리 영역으로 일반적인 C 스택을 사용
예시 코드를 통해 확인
public class Example {
static int staticVar = 10;
final int instanceVar = 5;
public static void main(String[] args) {
int localVar = 20;
Example ex = new Example();
ex.method();
}
public void method() {
int methodVar = 30;
System.out.println(staticVar + " " + instanceVar + " " + methodVar);
}
}
1. Heap 영역
Example 클래스의 인스턴스(객체)가 저장
- 인스턴스 변수
instanceVar의 값
2. Method 영역
Example 클래스의 메타데이터
- 클래스 이름, 부모 클래스 정보, 메서드 및 변수의 시그니처 등
- 정적 변수
staticVar의 값
- 모든 인스턴스가 공유하는 변수이기 때문에 Method 영역에 저장
10 , 5, 20, 30
main 및 method 메서드의 바이트코드(메서드의 코드 자체)
3. JVM Stack 영역
main 메서드를 위한 스택 프레임이 생성
- 이 stack frame 안에
localVar와 ex 참조 변수, args 매개 변수 저장
ex는 Heap에 저장된 Example 객체를 가리킴
method 메서드 호출될 때, 스택 프레임 생성
4. PC 레지스터 영역
- 현재 실행 중인 각 스레드의 명령어 주소가 저장
main 메서드를 실행 중인 스레드는 main 내의 현재 실행 중인 명령어의 주소 가지고 있음
method를 실행하는 동안에는 method 내의 현재 실행 중인 명령어의 주소 가지고 있음
5. Native Method Stack 영역
- 직접적으로 네이티브 메서드 호출이 없음
System.out.println 메서드 같은 내부적으로 네이티브 코드를 호출하는 메서드가 실행될 때 이 영역이 사용될 수 있음
참고 자료
https://coding-factory.tistory.com/828