JVM은 자바 가상머신으로 자바 바이트코드를 실행 할 수 있는 주체로 JVM 덕분에 CPU나 운영체제(플랫폼)과 독릭접으로 동작 가능하다.
JVM은 크게 Class Loader,GC, Runtime Data Area, Excute engine 세가지로 나뉜다
JVM 구성요소
1. Class Loader
컴파일된 자바 바이트코드를 Runtime Data Area 영엑에 로드한다.
자바 컴파일러가 ,java 파일을 컴파일하면 .class 파일 을 만드는데, 이게 바로 바이트코드이고 이걸 데이터영역에 로드하는 것이다.
javac 가 바이트코드로 컴파일을 하게 되는데 이건 jdk 에 있는 기능이다. JRE 는 실행환경이기 때문에 컴파일 기능이 없다.
자바 9 이후 부터는 JRE 가 따로 제공되지 않는다.
2. Excute engine
Class Loader 를 통해 JVM 내의 Runtime Data Area 에 배치된 바이트코드를 실행한다.
실행엔진으로는
명령어를 하나 하나 실행하는 인터프리터 방식과
실행 시점에 자주 쓸만한 코드들을 기계어로 변환 시켜놓고 저장해서 사용하는 JIT 방식이 있다.
다시 말하면 JIT 컴파일러는 자주 사용되는 코드일 경우에만 기계어로 캐싱하고 그 부분이 호출이 되면 실행이 된다.
여기 실행엔진에 GC 를 넣는 사람이 있고, 실행엔진과 별개로 JVM 의 큰 범주로 나누는 사람이 있다.
GC 란 Heap 메모리 영역에 생성 된 객체들 중 사용하지 않는 객체를 탐색 후 제거하는 역할을 하는 것이다.
여기서 런타임 데이터영역은 또 여러가지 구조로 나뉜다.
3. Runtime Data Area
JVM의 메모리 영역으로 자바 애플리케이션을 실행할 때 사용되는 데이터들을 적재하는 영역이다.
이 영역은 크게 Method Area, Heap Area, Stack Area, PC Register, Native Method Stack로 나눌 수 있다.
1. Method area (메소드 영역)
클래스 멤버 변수의 이름, 데이터 타입, 접근 제어자 정보같은 필드 정보와 메소드의 이름, 리턴 타입, 파라미터, 접근 제어자 정보같은 메소드 정보, Type정보(Interface인지 class인지), Constant Pool(상수 풀 : 문자 상수, 타입, 필드, 객체 참조가 저장됨), static 변수, final class 변수등이 생성되는 영역이다.
2. Heap area (힙 영역)
new 키워드로 생성된 객체와 배열이 생성되는 영역이다.
메소드 영역에 로드된 클래스만 생성이 가능하고 Garbage Collector가 참조되지 않는 메모리를 확인하고 제거하는 영역이다.
3. Stack area (스택 영역)
지역 변수, 파라미터, 리턴 값, 연산에 사용되는 임시 값등이 생성되는 영역이다.
동적으로 객체를 생성하면 실제 객체는 Heap에 할당되고 해당 레퍼런스만 Stack에 저장된다. Stack은 스레드별로 독자적으로 가진다.
int a = 10; 이라는 소스를 작성했다면 정수값이 할당될 수 있는 메모리공간을 a라고 잡아두고 그 메모리 영역에 값이 10이 들어간다. 즉, 스택에 메모리에 이름이 a라고 붙여주고 값이 10인 메모리 공간을 만든다.
클래스 Person p = new Person(); 이라는 소스를 작성했다면 Person p는 스택 영역에 생성되고 new로 생성된 Person 클래스의 인스턴스는 힙 영역에 생성된다.
그리고 스택영역에 생성된 p의 값으로 힙 영역의 주소값을 가지고 있다. 즉, 스택 영역에 생성된 p가 힙 영역에 생성된 객체를 가리키고(참조하고) 있는 것이다.
메소드를 호출할 때마다 개별적으로 스택이 생성된다.
Heap에 있는 오브젝트가 Stack에서 참조 할 수 없는 경우 GC의 대상이 된다.
4. PC Register (PC 레지스터)
Thread(쓰레드)가 생성될 때마다 생성되는 영역으로 Program Counter 즉, 현재 쓰레드가 실행되는 부분의 주소와 명령을 저장하고 있는 영역이다. (*CPU의 레지스터와 다름)
이것을 이용해서 쓰레드를 돌아가면서 수행할 수 있게 한다.
5. Native method stack
자바 외 언어로 작성된 네이티브 코드를 위한 메모리 영역이다.
보통 C/C++등의 코드를 수행하기 위한 스택이다. (JNI)
쓰레드가 생성되었을 때 기준으로
1,2번인 메소드 영역과 힙 영역을 모든 쓰레드가 공유하고,
3,4,5번인 스택 영역과 PC 레지스터, Native method stack은 각각의 쓰레드마다 생성되고 공유되지 않는다.
JIT 컴파일러란(Just-In-Time)
JRE안에 존재하고,
사용하는 이유는 같은 코드를 매번 해석하지 않고 실행할 때 컴파일을 하면서 해당코드를 캐싱한다.
이후엔 바뀐 부분만 컴파일 하고 나머지는 캐싱된 코드를 사용해서 인터프리터의 속도를 개선하는 역할을 한다.
JDK와 JRE의 차이
-
JDK = JRE + @ 이며
-
JRE는 읽기 전용, JDK 읽기 / 쓰기 전용이라 생각할 수 있다.
JRE(Java Runtime Enviroment) : 컴파일된 자바 프로그램을 실행시킬 수 있는 자바 환경
JDK(Java Development kit) : 자바 프로그래밍시 필요한 컴파일러 등 포함
Runtime Data Area 및 JIT 컴파일러에 대해서는 따로 포스팅 할 예정이다.
'Java > Java 기본 및 이론' 카테고리의 다른 글
[Java] 자바 기본 제어문 - 선택문, 반복문 (0) | 2021.01.11 |
---|---|
[Java] junit5 설명 및 기본 사용 - junit4 와 5 비교 (0) | 2021.01.11 |
[Java] 자바의 연산자 (0) | 2021.01.07 |
[Java] 자바의 프리미티브 타입, 변수 그리고 배열을 사용하는 방법 (0) | 2021.01.03 |
[Java] 자바 UnsupportedClassVersionError 원인 (javac -target) (0) | 2020.12.28 |