남궁성님의 Java의 정석(3rd Edition)을 보고 정리한 글입니다.
1. JVM(Java Virtual Machine) 구조와 동작방식
Java 소스파일(.java)
개발자가 작성한 Java 소스코드 파일이다.
Java 바이트코드(.class)
Java 컴파일러(javac)가 Java 소스코드 파일을 Java 바이트코드로 컴파일한다.
Class Loader(클래스 로더)
Java는 클래스를 동적으로 로딩합니다. 클래스로더가 바이트코드(.class)들을 읽어서 필요 시점에 동적으로 Runtime Data Area 영역에 동적 적재한다.
Execution Engine(실행엔진)
클래스 로더를 통해 Runtime Data Area 에 배치된 바이트코드를 읽어서 명령어 단위로 해석하고 바이트 코드를 실제 JVM 내부에서 기계가 실행할 수 있는 형태로 변경해준다.
실행엔진은 수행 과정에서 인터프리터, JIT 컴파일 두 가지 방식으로 바이트 코드를 실행한다.
1. 인터프리터(Interpreter): 바이트코드 명령어를 하나씩 읽어서 실행
2. JIT 컴파일러(Just-In-Time Compiler): 바아티코드 전체를 읽어 네이티브 코드로 변경
JIT 컴파일러가 인터프리터보다 실행속도가 빠르지만, 더 많은 비용이 소모된다. 평소에는 인터프리터 방식을 사용하다가 일정 기준이 넘어가면 JIT 컴파일 방식으로 진행한다.
Garbage Collector(가비지 컬렉터)
Java의 메모리 관리방법으로 동적으로 할당했던 Heap 영역에 필요없게 된 메모리를 주기적으로 제거하는 프로세스이다.
method Area나 Stack Area에서 객체가 참조하고 있지 않으면 해당 객체는 가비지 컬렉션의 대상이 되고 이러한 객체들은 Unreachable 하다고 하고, 주기적으로 가비지 컬렉터가 제거
/2. Runtime Data Area(런타임 데이터 영역)
Method Area(메서드 영역)
- 클래스 인터페이스에 대한 정보(Runtime Constant Pool), static 변수, static 메서드 등을 보관한다.
- 바이트코드(.class)를 처음 메모리 공간에 올릴 때 초기화되는 대상(클래스를 생성할 때 참조해야 할 정보)을 저장하여 참조하고 중복을 막는 역할을 수행한다.
- JVM 시작시 생성하고 종료시까지 사용(명시적 NULL 선언시 GC 대상)
- 모든 스레드에서 공유
Heap Area(힙 영력)
- 데이터를 저장하기 위해 런타임시 동적으로 할당하여 사용하는 메모리 영역
- new를 통해 생성한 객체를 저장
- 스택영역과 메서드영역에서 참조하지 않을 때(쓰이지 않을 때) GC 대상
- 모든 스레드에서 공유
Stack Area(스택 영역)
- 메서드가 호출되면, 수행에 필요한 메모리가 할당된다.
- 생서되는 스레드 수행정보를 기록하는 Frame, 메서드 정보, 지역변수, 매개변수 연산 중 발생하는 임시 데이터 저장
- 메서드 수행을 마치면 사용했던 메모리를 반환한다.
- Stack 구조(LIFO)
- 각 스레드별로 생성
PC Register
- 현재 스레드가 실행되는 부분의 주소와 명령을 저장
- 각 스레드별로 생성
Native Method Stack
- 실제 실행할 수 있는 기계어로 작성된 프로그램이나, 자바 이외의 언어(C, C++ 어셈블리 등)로 작성된 코드를 실행하기 위한 공간
- 각 스레드별로 생성
'Programming > Java' 카테고리의 다른 글
[Java] 오버로딩과 오버라이딩 (0) | 2023.10.13 |
---|---|
[Java] 매개변수를 전달하는 방법(기본타입, 참조타입) (0) | 2023.10.13 |
[Java] 배열(Array) (0) | 2023.10.09 |
[Java] 조건문과 반복문 (1) | 2023.10.09 |
[Java] 변수(Variable) (0) | 2023.10.09 |