- JVM에는 6가지 메모리 영역이 존재한다.
- Stack
- Heap
- PC Register
- Native Method Stack
- Method
- Stack
- Stack 영역은 스레드 마다 생성된다. Stack은 스레드의 생성과 종료에 따라 생성되고 소멸된다.
- Primitive 원본 값을 저장한다. 또는 Heap 영역에 대한 객체의 참조값이 저장된다.
- Heap
- Heap 영역에는 객체가 저장된다. new Object 와 같이 객체를 생성하면 저장되는 공간이다.
- 스레드에 관계없는 공유자원이다. (Heap은 스레드 안전하지 않다.)
- PC Register
- 현재 스레드가 실행시킬 명령어에 대한 정보를 지니고 있다.
- Stack 처럼 스레드 마다 생성된다.
- Method (Java8 이전 기준으로 Permanent Gen, Java8 이후로는 Metaspace 영역에 해당)
- 클래스, 인터페이스의 정보가 저장된다.
- 클래스의 메서드와 타입, 매개변수 타입 정보등이 저장된다.
static
키워드가 붙는 변수, 메서드 역시 메서드 영역에 저장된다.- Java8 이전 버전까지는 Permanent Gen 영역에 저장되었으나, Java8 이후 부터는 Metaspace에 저장된다.
- 주의할 것은 static 이어도 마찬가지로 원시 타입이 아닌 객체에 대해서는 레퍼런스만을 저장한다. 객체 값 자체를 지니는 것은 아니다.
- 이 중 가장 기본이 되는 Stack 과 Heap을 중점적으로 알아보자
- 코드로 알아보는 Stack 과 Heap의 구성
class Person { int id; String name; public Person(int id, String name) { this.id = id; this.name = name; } } public class PersonBuilder { private static Person buildPerson(int id, String name) { return new Person(id, name); } public static void main(String[] args) { int id = 23; String name = "John"; Person person = null; person = buildPerson(id, name); } }
- main → buildPerson → Person 생성자 순으로 호출스택이 쌓인다. 호출이 끝나면서 관련된 Stack의 메모리 값들 역시 비워진다.
- main을 실행하는 스레드의 스택이 먼저 생성된다.
- main 함수
- id는 Stack 영역에 쌓인다.
- name의 String 값에 해당하는 “John”은 Heap 영역에 불변값으로 존재한다. 그리고 해당 값을 참조하는 정보를 stack 에 쌓는다.
- person은 Heap 영역에 생성된다. 마찬가지로 Heap 영역에 생성된 실체 객체를 참조하는 정보가 stack에 쌓인다.
- Heap 영역의 세부사항
- Heap에 대해 조금 더 들어가면, 다음과 같은 3가지 영역으로 구분할 수 있다.
- Young Generation
- 객체의 생명이 짧은 것들이 저장되는 공간
- 주로 최근 생성된 객체가 저장되는 공간
- 여기서 발생하는 GC는 마이너 GC라 한다.
- Old Generation
- 객체의 생명이 긴 것들이 저장되는 공간
- 생성이후 오래되어, 더이상 참조되지 않는 객체를 저장하는 공간
- 여기서 발생하는 GC는 메이저 GC라 한다.
- Permanent Generation (Java8 이후에는 Metaspace로 대체)
- 클래스 정보, Method 정보가 저장된다.
- Metaspace
- 현재까지 load한 클래스정보들이 저장되는 공간.
- 정확히 Metaspace 영역은 Heap 영역이 아니라 Native Memory 영역에 위치한다.
요약
요약: