자바 프로그램을 실행하면 JVM 프로세스가 실행되고, JVM 프로세스 안에서는 여러 개의 스레드가 실행된다.
그리고 각 스레드마다 Java Stack, PC Register, Native Method Stack 이 할당된다.
JVM의 메모리는 Thread 마다 생성되는 데이터 영역과 전체 Thread가 공유하는 데이터 영역(heap, method area)으로 나뉘며, 해당 공간을 합쳐서 Runtime Data Areas 라고 부른다.
- Heap: new 명령어로 생성된 인스턴스나 객체가 저장되며, Garbage Collector에 의해 관리된다.
- Method Area: 필드, 메소드의 메타 정보, static 변수 등이 저장된다.
- Thread: Process의 작은 작업 단위
- PC: Thread의 작업 상태를 저장
- JVM Stack: 로컬 변수, 일부 실행 결과, 메소드 호출 또는 반환 등을 저장
- native method stack: 자바 이외의 언어로 작성된 코드를 실행할 때 할당되는 공간
User Level Thread: 사용자 라이브러리를 통해 사용자가 만든 스레드로, 스레드가 생성 된 프로세스에 의해 제어된다.
- 커널은 User Level Thread에 대해 알지 못한다.
- CPU 스케쥴러에 의해 관리되기 위해서, User Level Thread는 Kernel Level Thread에 매핑되어 실행된다.
Kernel Level Thread: 커널에 의해 생성되고 OS에 의해 직접 관리된다.
- User Level Thread에 비해서 생성 및 관리 속도가 느리다.
여러 User Level Thread가 하나의 Kernel Level Thread로 매핑되는 다대일 구조를 가진다.
하나의 User Level Thread가 Blocked 상태가 되면 전체 프로세스가 Blocked 상태가 된다.
- 멀티 코어 시스템에서 병렬로 실행될 수 없다.
One-to-One Model은 각각의 User Level Thread가 하나의 Kernel Level Thread와 매핑된다.
- 하나의 User Level Thread가 Blocked 상태가 되더라도 다른 스레드에 영향을 주지않아 병렬로 실행이 가능하다.
User Level Thread 수만큼 Kernel Level Thread가 있어야한다.
- 많은 수의 Kernel Level Thread는 부하를 줄 수 있기 때문에 Window, Linux 운영체제에서는 최대 스레드 수를 제한한다.
JDK21부터 Release 된 경량 스레드로 처리량이 우수하며, Virtual Thread는 JVM 내부 스케쥴링에 의해 관리된다.
Carrier Thread = Platform Thread
- Thread가 Blocking 상태가 되면, Platform Thread 자체도 Blocking 상태가 된다.
- Virtual Thread에서는 가상 스레드가 Blocking 되더라도, Carrier Thread는 또다른 Virtual Thread를 마운트한다.
- CPU Utilization 극대화 = 처리량 증가!
- 저렴한 Context Switching: Native Thread Model에서는 Context Switching이 OS에서 발생하지만, Virtual Thread에서는 JVM 내부에서 이루어진다.
https://hongsii.github.io/2018/12/20/jvm-memory-structure/
https://e-una.tistory.com/70
https://www.youtube.com/watch?v=Q1jZtN8oMnU&t=25s