Java의 Memory 영역
Java 프로그램이 실행되면 JVM(Java Virtual Machine)은 OS로부터 메모리를 할당받고, 그 메모리를 용도에 따라 여러 영역으로 나누어 관리한다.
JVM의 메모리 공간(Runtime Data Area)은 크게 Method(Static) 영역, Stack 영역, Heap 영역으로 구분되고 Data Type에 따라 각 영역에 나누어 할당 된다.
컴퓨터의 메모리는 사용 가능한 공간이 한정되어 있기 때문에 어떻게 관리하느냐에 따라 프로그램의 성능이 좌우된다. 따라서 같은 기능의 프로그램이라 하더라도 메모리 관리에 따라 성능 차이가 크게 나타난다. 따라서 Java Application에서 메모리를 효율적으로 사용하기 위해 메모리 구조와 특징, GC의 동작 방식에 대해 이해할 필요가 있다.
Stack과 Heap에 대해 자세히 알아보자.
Stack
Stack Frame(또는 Activation Record)을 저장하는 메모리 공간이다. Stack Frame은 메서드가 호출되기 전 상태를 기록하는 역할을 수행하며, 아래와 같은 내용을 포함한다.
- 매개 변수(Parameter) : 호출 메서드가 전달한 인자 값
- 지역 변수(Local Variable) : 메서드 내에서 선언한 변수
- 리턴 주소(Return Address) : 메서드 실행을 마친 다음 실행할 명령문의 주소
- 리턴 값(Return Value) : 호출 메서드에게 돌려줄 값
즉, 메서드 내에서 정의하는 기본 자료형(Primative Type / int, double, byte, long, boolean 등)에 해당되는 지역 변수와 매개 변수의 데이터 값은 Stack Frame에 포함되어 Stack Area(스택 메모리 영역)에 저장된다. Stack Frame은 메서드가 호출될 때 메모리에 할당(Push)되고, 종료되면 메모리에서 제거(Pop) 된다.
위의 내용처럼 기본형 타입의 변수들은 Stack 영역에 저장되는 반면, 참조형 타입 변수는 참조값만 저장되고, 실제 객체들은 Heap 영역에 저장된다. 즉, Stack 메모리 영역에서는 Heap 영역에 존재하는 객체들에 대한 참조를 가지고 있다.
Stack Memory의 Top에 존재하는 하나의 Stack Frame만 활성화되며, 그 이전에 존재하는 Stack Frame은 모두 비활성화 된다. 비활성화된 Stack Frame의 지역변수에는 접근이 불가하다. 위의 이미지를 다시 보면 Stack Memory가 여러 겹으로 중첩되어 있는 것을 확인 할 수 있는데, 이는 Stack Memory 영역이 Thread 별로 할당되기 때문이다.
Thread가 생성되고 시작될 때마다 각각의 Stack Memory를 가지게 되며, 다른 Thread의 Stack Memory에 Access 할 수 없다.
Heap
Heap Memory 영역에는 실제 객체가 저장된다. Heap 영역에 존재하는 객체들은 Stack 영역의 변수들에 의해 참조된다. 아래의 예제를 통해 살펴보자.
StringBuilder builder = new StringBuilder();
new 라는 키워드는 heap 영역에 StringBuilder라는 객체를 생성하기 위한 빈 공간이 충분한지 확인해야하고, Stack에 있는 builder라는 변수를 통해 참조되도록 보장한다.
따라서, 실행 중인 각 JVM 프로세스에 대해 Stack과 달리 Heap 영역은 단 하나만 존재한다. 실행 중인 Thread 수에 관계 없이 Heap 영역에 존재하는 Memory는 공유된다.
위의 이미지는 Heap 구조를 보기 편하게 그렸지만, 사실 Heap 자체는 Garabge Collector 프로세스를 용이하게 하는 몇 개의 부분으로 나뉜다.
Reference Type에 대한 종류와 Garbage Collection Process에 대해서는 다음 포스팅에서 자세히 알아보자~! 👀
'🌱Java | Spring' 카테고리의 다른 글
[Java] Throw vs Throws (0) | 2023.04.09 |
---|---|
[Java] Java의 메모리 관리(2) (0) | 2022.07.31 |
[Spring] Filter vs Interceptor (0) | 2022.07.18 |
[Spring] Spring MVC (0) | 2022.06.30 |
[Java] 추상클래스 vs 인터페이스 (0) | 2022.06.14 |