JVM 구조
- Class Loader
- .java -(javac가 컴파일)-> .class - (jvm) -> Runtime Data Area 로 적재.
- Execution Engine
- classLoader에 의해 메모리에 적재된 클래스(바이트콛)들을 기계어로 변경하여 명령어 단위로 실행하는 것.
- 명령어 실행 방식 2가지
- 인터프리터 : 명령어를 하나씩 수행.(기본적 방식,전체 수행 느림 하지만 명령어 하나의 동작 빠름)
- Just In Time compiler(JIT) : 바이트 코드 -> 네이티브코드로 변환 후 인터프리팅하지 않으며 네이티브 코드로 실행 (실행 동작은 빠르지만 컴파일하는데 시간이 많이 소요.)
- 명령어 실행 방식 2가지
- classLoader에 의해 메모리에 적재된 클래스(바이트콛)들을 기계어로 변경하여 명령어 단위로 실행하는 것.
- Garbage Collector
- GC는 Heap메모리 영역에 생성된 객체들 중 참조되지 않는 객체들을 제거하는 역할.
- GC의 동작시간은 일정하지 않고 언제 객체를 정리 할 지 모른다. 바로 참조가 없어지자마자 동작하는 것이 아니다.
- GC를 수행하는 동안 GC 스레드를 제외한 다른 모든 스레드 정지.(수초간 GC로 인하여 다른 스레드가 정지한다면 큰 장애 유발.)
- Runtime Data Area
- 데이터를 적재하는 영역.
- Method Area
- JVM에서 읽은 클래스와 인터페이스 정보가 저장되는 영역이며, 클래스 생성자 및 메소드의 코드(바이트 코등)등이 저장.
- 클래스의 인스턴스가 생성된 후, 메소드가 실행되는 순간 클래의 정보가 Method Area 에 저장.
- 모든 쓰레드에 의해 공유되는 영역이며, JVM이 시작될 때 생성된다.
- 내부에 Runtime Constant Pool 영역을 가지고 있다.
- Runtime Constant 영역(물리적인 메모리 위치를 참조할 경우 사용)
- class
- Interface
- Method
- Field
- String Constant ... Reference가 저
- Method Area
-
- Heap Area
- new 키워드로 생성된 객체와 배열의 생성 영역.
- 객체의 LifeCycle 과 GC와 연관되어 있다.
- Method Area에 로드된 Class만 생성 가능하며 GC가 참조되지 않은 메모리를 확인하고 제거하는 영억
- Stack Area
- 메소드 호출시 수행중인 메소드 데이터를 저장하기 위한 영역.
- 메소드 데이터
- Local Var
- Local Object Ref
- Method Parameter
- Method Return Value
- 메소드 데이터
- 스레드 별로 각각 독립적으로 생성된다.
- stack Frame이 생성되어 Push하고 , 메소드 생성이 완료되면 stackFrame에서 pop되어 사라짐.
- 메소드 호출시 수행중인 메소드 데이터를 저장하기 위한 영역.
- PC register
- 스레드가 생성될 때마다 할당 되는 영역으로 PC(Programe Counter)이다.
- 쓰레드가 실행할 JVM명령(바이트코드의 명령)의 주소를 저장.
- 여러 바이트코드 명령어들이 나열된 형태가 되고 JVM은 명령을 하나씩 실행해나가며 java 애플리케이션을 실행한다.
- 현재 쓰레드가 실행되는 부분의 주소와 명령을 저장하는 영역.(쓰레드가를 돌아가면서 수행)
- Native Method Stack
- 자바의 언어로 작성된 네이티브 코드를 위한 메모리 영역
- 보통 c/c++등의 코드를 수행하기 위한 스택(JINI)
- Heap Area
- 데이터를 적재하는 영역.
더보기
mirinae312.github.io/develop/2018/06/04/jvm_memory.html
힙 영역 자세히 보기
- Eden 영역(Young영역)
- 새로 생성된 객체가 처음 위치하는 영역
- 정기적으로 GC가 발생한 후, 살아남은 객체들의 surivivor1,2의 영역으로 만 이동하여 계속 쌓인다.
- Survivor1,2 영역(Young영역)
- survivor 1,2의 영역이 가득차면, 그 중 살아남은 객체가 비워진 survivor영역으로 이동.
- 이때 참조가 없는 객체들을 메모리에서 정리된다.
- 이러한 매커니즘으로 인해 survivor1이나 2는 항상 비워진 상태가 되며, 영역중 하나가 비워지지 않는다면 문제가 발생한 것이다.
- Old영역
- survivor1 또는 2영역을 왔다갔다 하다가 끝까지 살아남은 객체만이 Old영역으로 이동하게 된다.
- old영역은 Young영역보다 크게 할당 되며, 이러한 이유로 old영역의 GC는 Young영역보다 적게 발생한다.
- Permeanent 영역
- 클래스 로더에 의해 로드된 클래스들이 저장되는 공간이다.
- java8에서는 이 영역이 바뀌어 Meraspace라는 영역으로 바뀌었다.
- ※ JVM 메모리 영역에서의 객체의 LifeCycle
버전에 따른 변경사항
Java 8에서 JVM의 변화 : PermGen이 사라지고 Metaspace가 등장
Permanent Generation 메모리 영역이 없어지고 Metaspace 영역이 생김.
- Permanent Generation
- class 혹은 Method Code가 저장되는 영역이다.
- Heap영역에 속한다.
- Default 제한된 크기를 갖고 있다.
- Metaspace
- Java의 classLoader가 현재까지 로드한 class들의metadata가 저장되는 공간.
- Native 메모리 영역 위치.
- Default 크기가 아니다.
JVM에 관리되는 Heap이 아닌 OS레벨에서 관리되는 Native영역.
metaspace가 native메모리를 이용함으로써 개발자는 영역 확보의 상한을 크게 의식 할 필요가 없게 된다.
Metaspace 장/단점.
장점.
- 이제는 더이상 java.lang.OutOfMemoryError : PermGen space와 같은 문제를 더이상 야기하지 않는다는 것.
- tunning과 monitoring을 통해서 이러한 memory space를 조절할 필요가 없다는 것.
단점
- class의 메모리 공간을 줄여주거나 class loader의 memory leak을 줄여주지는 못하는 것.
'JAVA' 카테고리의 다른 글
Garbage Collector (0) | 2021.04.25 |
---|---|
Reflection (0) | 2021.04.16 |
제네릭 타입의 컴파일 영향 (1) | 2021.04.10 |
자바의 compile 과정 (0) | 2021.04.04 |
Wrapper Class 와Primitive Type and First Class Collection (0) | 2021.03.21 |
댓글