Java 프로그램은 실행 중 메모리를 효율적으로 사용하기 위해 JVM(Java Virtual Machine)이 메모리를 다양한 영역으로 나눠 관리한다.
- 메모리 영역 개요
메모리 영역 | 설명 |
---|---|
Heap | 객체와 인스턴스 변수가 저장되는 영역. Garbage Collector(GC)가 사용되지 않는 객체를 자동으로 해제 |
Stack | 메서드 호출시 생성되는 로컬 변수와 참조 변수를 저장. 메서드 호출이 끝나면 자동으로 해제. |
Method Area | 클래스 정보, static 변수, 상수, 메서드 코드(Bytecode) 등을 저장. |
Program Counter | JVM이 현재 실행 중인 명령의 주소를 저장. |
Native Method Stack | C/C++ 같은 네이티브 코드를 실행할 때 사용하는 스택. |
Heap 영역
객체와 인스턴스 변수를 저장
동적으로 메모리를 할당받는 객체가 저장된다.
프로그램 실행 중 JVM이 관리하며, Garbage Collector가 더 이상 참조되지 않는 객체를 자동으로 제거한다.
모든 스레드가 공유한다.
public class Main {
public static void main(String[] args) {
Car car = new Car(); // car 객체가 Heap 영역에 생성
}
}
car 객체는 Heap에 생성되고, car 변수는 Stack에서 이를 참조한다.
Stack 영역
메서드 호출시 생성되는 로컬 변수와 참조 변수 저장
LIFO(Last In, First Out) 구조로 메서드 호출시 데이터를 저장하고 종료시 제거한다.
스레드 단위로 할당된다.
빠르게 할당/해제가 가능하다.
객체 자체는 저장되지 않고, 객체의 참조값이 저장된다.
Stack Memory와 Stack Area는 동일한 개념이다. Heap Memory와 Heap Area도 같은 개념이다.
public class Main {
public static void main(String[] args) {
int a = 10; // a는 Stack에 저장
Car car = new Car(); // car는 Stack에 참조값 저장, 실제 객체는 Heap에 저장
}
}
Method Area(메서드 영역)
JVM의 메모리 구조 중 하나로 클래스 로드시 필요한 정보를 저장한다.
프로그램 실행 중 JVM이 처음 클래스를 로드할 때 초기화된다.
클래스에 대한 메타데이터, static 변수, 메서드 코드(Bytecode)와 상수(Constant Pool) 등이 저장된다.
모든 스레드가 공유하는 영역으로 프로그램 전체에서 공통적으로 사용된다.
메모리 부족시 JVM은 OutOfMemoryError를 발생시킨다.
클래스 로드시 초기화되며 이후 JVM이 해당 클래스를 참조할 땐 이미 로드된 정보를 사용한다.
Method Area에 저장된 데이터는 Garbage Collector에 의해 정리되지 않는다.
그러나 Java 8 이전의 Permanent Generation에선 수동 관리로 인해 메모리 누수가 발생할 수 있었다. 이를 Java 8부터 Metaspace로 개선했다.
Permanent Generation(영구 세대)
Permanent Generation은 Java 7 이하의 JVM에서 클래스와 관련된 메타데이터 및 static 변수, 상수를 저장하기 위해 사용되던 Heap 메모리 영역의 한 부분이다. Java 8부턴 Metaspace란 새로운 메모리 구조로 대체되었다. 줄여서 PermGen이라 한다.
역할
Java 7 이하의 JVM에서 클래스 수준의 데이터를 저장하던 메모리 영역이다.
Heap 내부에 위치하며 정적 데이터를 저장하기 위해 사용되었다.
PermGen엔 다음과 같은 데이터가 저장된다.
- 클래스 정보
- 클래스 이름, 부모 클래스 정보, 메서드 이름 및 매개변수 정보 등
- JVM이 클래스를 로드할 때 저장된다.
- static 변수
- 클래스의 static 변수는 PermGen에 저장되며 모든 객체가 공유한다.
- 상수(Constant Pool)
- 컴파일된 클래스 파일(.class)에서 상수 풀(Constant Pool) 데이터를 저장한다.
- 예: 문자열 리터럴("Hello")이나 상수 값
- 메서드 코드(Bytecode)
- 메서드의 바이트코드와 관련된 정보
PermGen은 크기가 제한적이며, 기본 설정으로 크기를 직접 지정할 수 있다.
JVM 옵션으로 PermGen 크기를 설정할 수 있다.
java -XX:PermSize=64m -XX:MaxPermSize=128m MyApp
PermSize: PermGen의 초기 크기
MaxPermSize: PermGen의 최대 크기
Program Counter (PC) Register
- 역할: 현재 실행 중인 명령의 주소를 저장
- 특징
- JVM의 각 스레드가 자신의 PC 레지스터를 가짐
- 현재 실행 중인 명령의 주소를 기억
Native Method Stack
- 역할: 네이티브 코드(C, C++) 실행을 위한 스택
- 특징
- JNI(Java Native Interface)를 통해 호출된 네이티브 메서드에서 사용
- 네이티브 메서드 호출시 네이티브 라이브러리와 상호작용
PC 레지스터(Program Counter Register)는 JVM에서 각 스레드가 실행 중인 현재 명령의 주소를 저장하는 레지스터이다. 이는 JVM이 명령어의 실행 흐름을 제어하는데 중요한 역할을 한다.
'프로그래밍' 카테고리의 다른 글
그래프(Graph) (3) | 2024.12.17 |
---|---|
Heap과 Stack (0) | 2024.12.12 |
static (1) | 2024.12.10 |
퀵 정렬(Quick Sort) (1) | 2024.12.10 |
이진탐색(binary search) (0) | 2024.12.10 |