JVM memory 구조
업데이트:
JVM이란?
- Java Virtual Machine
- 자바 바이트 코드를 실행할 수 있는 주체
- 자바와 운영체제 사이에서 중개자 역할을 수행
- 자바가 운영체제에 독립적으로 프로그램을 실행할 수 있도록 함
- 가비지 컬렉터를 사용한 메모리 관리도 자동으로 수행
JVM 메모리 구조 및 동작 과정
JVM의 구조
- 크게 Class Loader, Execution Engine, Runtime Data Area로 나뉨
- Class Loader System
- JVM이 운영체제로부터 할당받은 메모리영역인 Runtime Data Area로 바이너리 코드(.class 파일)를 적재하는 역할수행
- 로딩
- 클래스를 읽어오는 과정
- 링크
- 레퍼런스를 연결하는 과정
- 초기화
- static 값들을 초기화 및 변수에 할당
- Execution Engine
- Class Loader에 의해 메모리에 적재된 바이트 코드를 기계어로 변경해 명령어 단위로 실행하는 역할수행
- Garbage Collector
- Heap 영역에 로딩된 인스턴스들 중 unreachable한 인스턴스들을 탐색 후 제거
- JIT (Just In Time) Compiler
- 인터프리터의 효율을 높이기 위해, 인터프리터가 반복되는 코드를 발견하면 JIT compiler로 반복되는 코드를 모두 네이티브 코드로 바꿔 둠
- 인터프리터는 바이트 코드를 한줄씩 실행함.
- 이후, 인터프리터는 네이티브 코드로 컴파일된 코드를 바로 사용
- 인터프리터의 효율을 높이기 위해, 인터프리터가 반복되는 코드를 발견하면 JIT compiler로 반복되는 코드를 모두 네이티브 코드로 바꿔 둠
- Runtime Data Area (memory)
- 자바 애플리케이션을 실행할 때 사용되는 데이터들을 적재하는 영역
- 크게 Method, Heap, Stack, PC Register, Native Method Stack으로 나뉨
- Method, Heap은 모든 스레드에서 공유하는 자원.
- Stack, PC Register, Native Method Stack은 각 thread에 국한된 자원.
Runtime Data Area
- Heap
- 클래스로부터 생성된 인스턴스와 배열이 저장
- 멤버 변수의 크기에 따라 메모리가 생성
- Heap에 할당된 인스턴스는 GC의 대상이 됨
- 모든 스레드에 의해 공유될 수 있는 자원
- 즉, 공유메모리 라고도 함
- Static (= Method area)
- 클래스 수준의 정보 (클래스 이름, 부모 클래스 이름, 메소드, 변수) 저장.
- Class Loader가 적재한 클래스(또는 인터페이스)에 대한 메타데이터 정보가 저장.
- package, class, interface, method에 대한 메타 데이터가 저장됨
- 패키지나 클래스는 프로그램 시작과 동시에 모두 로딩시키는 것이 아니라, 실제로 호출 될 때 로딩.
- 이 영역에 등록된 class의 인스턴스만이 Heap에 로딩될 수 있다.
- 정적 변수 저장
- 프로그램이 메모리에 로드될 때 생성되어 프로그램이 종료되고 메모리를 해제할 때까지 그 상태를 유지
- 인스턴스의 생성과 상관없이 사용가능.
- 사실 Method Area는 논리적으로 Heap의 일부. (java7 이전)
- 더 구체적으로는 Heap의 PermGen이라는 영역내에 method area가 존재했는데, java8 이후로는 heap 외부의 네이티브 메모리 공간을 사용하는 Metaspace라는 OS가 관리하는 영역으로 대체됨.
- 제한적이고 런타임에 확장 할 수없는 JVM 프로세스 메모리를 사용하는 PermGen의 한계를 없애기 위함.
- 모든 스레드에 의해 공유될 수 있는 자원
- 클래스 수준의 정보 (클래스 이름, 부모 클래스 이름, 메소드, 변수) 저장.
- Stack
- Thread에 Method가 호출될 때 수행 정보(메소드 호출 주소, 매개 변수, 지역 변수, 연산 스택)가 Frame 이라는 단위로 JVM stack에 저장.
- Method 호출이 종료될 때 stack에서 제거.
- 스레드간 공유될 수 없는 자원
- 스레드마다 런타임 스택을 갖고 그 안에다가 메서드가 호출될 때마다 스택 프레임(method call)을 쌓는다.
- stack은 각 스레드마다 하나씩 생성되는 영역.
- Thread에 Method가 호출될 때 수행 정보(메소드 호출 주소, 매개 변수, 지역 변수, 연산 스택)가 Frame 이라는 단위로 JVM stack에 저장.
- PC register
- 쓰레드마다 쓰레드 내 현재 실행할 스택 프레임을 가리키는 포인터
- 각 스레드마다 하나씩 생성되는 영역.
- native method stack
- native method를 호출할 때마다 쌓이는 별도의 stack.
- native method는 native 키워드가 붙어있는 method
- ex. Thread.currentThread() -> c로 짜여진 메서드
- JNI (Java Native Interface)
- native로 구현되어있는 코드를 호출할 수 있게 해주는 interface
- 각 스레드마다 하나씩 생성되는 영역.
댓글남기기