자바 프로그램 실행 과정을 복습하면서, JVM 구조와 역할에 대해 정리해보고자 한다.
- 더 나아가, 다음 글에는 Garbage Collector의 알고리즘을 정리해보려고 한다.
JVM을 통해 자바뿐만 아니라 Kotlin, JRuby 등 다른 언어로 작성된 프로그램 실행에 도움을 준다.
그래서 Java와 Kotlin을 각각 모듈화 해서 함께 사용할 수 있다.
📌 JVM
JVM을 통해 자바 바이트코드는 타겟 플랫폼에 상관없이 동작할 수 있다.
(여기서 타겟 플랫폼이란, Linux, Window, Android, iOS …)
- Java Source Code가 Javac라는 컴파일을 거친다.
- Java ByteCode가 생성된다.
- JVM을 통해 Java ByteCode를 Higer - low level 단계에 인터페이스가 되어, 다양한 OS에서 동작할 수 있게 도와준다.
Cross Platform을 쓰는 거랑 똑같지 않아?
- 자바는 다양한 환경(디바이스)에서 동작 가능한 장점이 있다.
- WEB, Mobile 등 거의 대부분의 환경에서 사용할 수 있다.
JVM 내부 살펴보기
- Method Area, Heap, Java Stacks, PC Registers, Native Method Stacks는 JVM이 자바 바이트코드를 실행하기 위해 사용하는 메모리 공간이다. (Runtime Data areas)
Execution Engine
실행 엔진은 클래스 로더를 통해 런타임 데이터 영역에 배치된 바이트 코드를 명령어 단위로 읽어서 실행합니다.
자바 바이트코드는 기계가 바로 수행할 수 있는 언어보다는 가상 머신이 이해할 수 있는 중간 레벨로 컴파일된 코드이다.
Interpreter
- 바이트코드 명령어를 하나씩 읽어서 해석하고 실행한다.
- 같은 메서드라도 여러 번 호출하기에, 매번 해석하고 수행해야 돼서 전체적인 속도가 느린 단점이 있다.
JIT Compiler
- 반복되는 코드를 발견하여 바이트 코드 전체를 컴파일하여 Native Code로 변경한다.
- 이후 해당 메서드를 더 이상 인터프리팅 하지 않고 캐싱해 두었다가 네이티브 코드로 직접 실행하는 방식이다.
- 여기서 네이티브 언어란, Java의 부모 언어가 되는 C, C++, 어셈블리어이다.
GC - Garbage Collector
JVM은 가비지 컬렉터를 통해 Heap 메모리 영역에서 더이상 사용하지 않는 메모리를 자동으로 회수해 준다.
Heap 메모리 영역에는 객체와 같은 Reference Type 데이터가 저장된다
Method Area
- Method Area는 클래스 로더가 클래스 파일을 읽은 후, 클래스 정보를 파싱 해서 저장하는 공간이다.
- JVM이 동작하고 클래스가 로드될 때 적재돼서 프로그램이 종료될 때까지 저장합니다.
- Runtime Constant Pool
- Method, Field
- Static 변수
Heap
- Heap은 프로그램을 실행하면서 생성된 모든 객체를 Heap에 저장한다.
- JVM이 프로그램 상에서 데이터를 저장하기 위해 런타임 시 동적으로 할당되는 영역이다.
- new 연산자로 생성되는 클래스와 인스턴스 변수, 배열 타입 등 Reference Type
- 힙 영역에 생성된 객체와 배열은 참조 타입으로서, JVM Stack 영역의 변수나 다른 객체의 필드에서 참조된다.
method area, Heap은 모든 스레드가 공유하는 공간이다.
📌 Heap 자세히 보기
- Young Generation (이름 처럼 젊다, 생성된 지 얼마 안 된 것들)
- Eden : new를 통해 새로 생성된 객체가 위치
- Survivor 1 / 2 : 정기적인 쓰레기 수집 후 살아남은 객체들이 이동
- Old Generation
- 생명 주기가 긴 객체를 GC 대상으로 하는 영역
Stack
- 자바 스택은 스레드 별로 1개만 존재한다.
- 기본 자료형을 생성할 때 저장하는 공간으로, 임시적으로 사용되는 변수나 정보들이 저장된다.
- 메서드가 호출될 때마다 생성(PUSH)되며, 실행이 끝나면 Stack Frame은 pop 되어 스택에서 제거된다.
- A → B 메서드 호출 → B → C 메서드 호출 …
- Stack Frame은 메서드가 호출될 때마다 Stack에 Push 된다.
- Local variable array, Operand stack, Frame Data
- Frame Data는 Constant Pool, 이전 스택 프레임에 대한 정보, 현재 메서드가 속한 클래스/객체에 대한 참조 등의 정보를 갖는다.
- Local variable array, Operand stack, Frame Data
📌 객체 생성 시 메모리에 어떻게 올라가는지
Person person = new Person("김현겸", 25);
- new에 의해 생성된 클래스는 Heap 영역에 저장된다.
- person 변수는 생성된 클래스의 참조 값을 Stack에 저장합니다.
program Counter Register
- 각 스레드는 메서드를 실행한다.
- PC 레지스터는 현재 수행 중인 JVM 명령어 주소를 저장한다.
Register란
프로그램 실행은 CPU의 명령으로 수행되는데, 연산을 수행하는 동안 필요한 정보를 레지스터에 관리한다.
- A, B데이터와 피연산 값인 Operand, 더하기 연산 (Instruction)
Native Method Stack
Java Bytecode가 아닌 다른 언어로 작성된 메서드를 관리한다.
→ 성능 향상 목적으로 다른 코드를 사용하는 경우, 여기에 관리되어 실행된다.
참고자료
https://inpa.tistory.com/entry/JAVA-☕-가비지-컬렉션 GC-동작-원리-알고리즘-💯-총정리
'JAVA' 카테고리의 다른 글
Java 21 가상 스레드란? 기존 OS 스레드와의 차이점 정리 (0) | 2025.02.18 |
---|---|
Java string, stringbuilder를 이용해 문자열 합치기 (0) | 2024.11.23 |
Java Record 컴팩트 생성자(compactconstructor) 이해하기 - record, @QueryProjection 적용 (0) | 2024.11.18 |
Java if문 최적화와 가독성 향상 방법 - 클린코드 작성 방법 (0) | 2024.11.12 |
[Java] Java Shutdown Hook 이란 - System.exit() (2) | 2024.09.25 |