JVM - Runtime Data Area - Thread

JVM 의 Runtime Data Area 중 Thread 영역에 대해서 알아봅니다.

Thread

  • PC 레지스터, java 가상 머신 스택, 네이티브 메서드 스택 등의 구성요소로 이루어짐
  • 이들 영역은 각 쓰레드에 별도로 할당되며, 쓰레드 간에 공유되지 않음
  • 각 쓰레드는 독자적인 실행 상태와, 메소드 호출 기록, 네이티브 스택을 갖게 됨

PC Register

  • 프로그램의 실행 흐름을 제어
  • 메소드 호출이나 분기, 루프 등에서 현재 어떤 명령어를 수행 할 지를 기억하고, 다음에 실행 할 위치를 저장
  • 매우 작고 단순한 데이터 ( 일반적으로 단일 정수 )를 저장하므로, 메모리 오버헤드는 거의 없음
  • 각 쓰레드는 독립적인 PC Register 를 갖기 때문에, 여러 쓰레드가 동시에 서로 다른 위치의 코드를 실행 할 수 있음

JVM Stack

  • Stack Frame의 구성
    • 로컬 변수 배열 → 메소드 매개변수와, 해당 메서드 내에 선언된 지역 변수들이 저장
    • 연산 스택 ( Operand Stack ) → 연산 중간 결과나 임시 데이터 등이 저장
    • Runtime 상수 Pool 참조 → 현재 메소드의 클래스 파일에 포함된 상수 ( 리터럴, 심볼 )에 대한 참조가 포함 될 수 있음
    • 리턴 주소 → 메소드 호출이 끝났을 때, 실행을 복귀할 위치 ( PC 레지스터의 값 )을 저장
  • 동작 방식
    • 메소드 호출 시
      • 메소드 호출이 이루어지면, 새로운 스택 프레임이 JVM Stack 에 push
      • 이 프레임에는, 해당 메소드 실행에 필요한 데이터가 저장
    • 메소드 반환 시
      • 메소드가 정상적으로 끝나면, 스택 프레임이 Pop 되어 제거되며, 이전 프레임으로 복귀
    • Last In / First Out 구조 → 가장 최근에 호출된 메소드의 정보가 가장 먼저 제거
  • 특성
    • 정적 크기
      • 기본적으로 각 쓰레드에는 -Xss 옵션으로 지정한 고정 크기의 스택이 할당
      • 재귀 호출 등으로 스택이 너무 깊어지면, StackOverflowError 가 발생 할 수 있음
    • 독립성
      • 각 쓰레드가 자신만의 JVM 스택을 가짐
      • 스택 내의 데이터는 쓰레드간에 공유 되지도 않고, 각 쓰레드의 상태를 안전하게 관리

Native Method Stack

  • 주요 역할
    • JNI ( Java Native Interface ) 를 통해, 호출되는 네이티브 메서드의 실행 컨텍스트 ( 지역 변수 / 호출 정보 ) 등을 저장
    • 네이티브 코드의 호출 스택은 일반적으로 운영 체제의 기능에 의해 관리 됨
  • 특징
    • 네이티브 메서드 스택은 JVM 스택과는 별도로 관리
    • 스택 크기를 JVM 옵션으로 지정할 수 있으나, 네이티브 라이브러리의 요구 사항에 따름
    • 모든 자바 쓰레드가 네이티브 메서드 스택을 반드시 사용하는것은 아니고, 네이티브 호출이 있거나 일부 라이브러리가 네이티브 메서드를 활용하는 경우에 주요 활용