JVM 이해
(Java Virtual Machine)
우리의 코드는 어떻게 실행 될까 ?
개발자 [ 자바파일(.java) > 자바컴파일러 > 바이트 코드 (.class) ]
> JVM(Java Virtual Machine) > OS(Operating System 윈도우..리눅스..맥 ) > 하드웨어
개발자는 코드를 만들어 JVM 으로 보낸다
JAVA는 OS에 종속적이지 않다는 특징을 가지고 있다 (대충 아무OS에서 다 돌아간단 얘기)
이러기 위에선 OS위에서 JAVA를 실행시킬 무언가가 필요하단 말이다.
이것이 JVM
JAVA 소스코드(*.java 자바파일)는 CPU가 인식을 하지 못하므로 기계어로 컴파일 해줘야 한다. 하지만 JAVA는 JVM 이라는 가상머신을 거쳐 OS에 도달하기 때문에 OS가 인식할 수 있는 기계어로 바로 컴파일 되는게 아니라
JVM이 인식할 수 있는 JAVA bytecode(*.class 클래스 파일)로 변환된다.
요약)
소스코드(*.java)는 CPU가 못읽으니까
JVM이 소스코드(*.java)를 -> JAVA bytecode(클래스파일)로 바꿔서
OS가 읽을수 있도록 해석 해준다.
JVM 구성
- 클래스 로더(Class Loader)
- 실행 엔진(Execution Engine)
- 인터프리터(Interpreter)
- JIT 컴파일러(Just-in-Time)
- 가비지 콜렉터(Gc)
- 런타임 데이터 영역 (Runtime Data Area)
1. 클래스 로더 (Class Loader)
JVM 내로 클래스 파일(*.class)을 로드하고, 링크를 통해 배치하는 작업을 수행하는 모듈이다.
런 타임시 동적으로 클래스를 로드하고 jar 파일 내 저장된 클래스들을 JVM 위에 탑재한다.
즉, 클래스를 처음으로 참조할 때, 해당 클래스를 로드하고 링크한는 역할을 한다.
- *.class 에서 바이트코드를 읽고 메모리에 저장
-package를 포함한 Class이름
(클래스,인터페이스,이넘 / 메소드,변수) - 로딩 : 클래스 읽어오는 과정
- 링크 : 레퍼런스를 연결하는 과정
- 초기화 : static 값들 초기화 및 변수에 할당
2. 메모리 영역 (Runtime Data Area)
런타임 데이터 영역(Runtime Data)은 실제 클래스 파일이 적재되는 곳으로 JVM이 OS로부터 자바 프로그램 실행을 위한 데이터와 명령어를 저장하기 위해 할당받는 메모리 공간이다. 주로 메소드, 힙, 스택 영역을 언급한다.
- 공유 자원
- 메소드 영역: 클래스 수준의 정보 (클래스 이름, 부모 클래스 이름, 메소드, 변수) 를 저장한다.
- 힙 영역: 객체(Instance)를 저장한다.
- 쓰레드 마다 사용하는 자원
- 스택 영역: 쓰레드 마다 런타임 스택을 만들고, 그 안에 메소드 호출을 스택 프레임이라 부르는 블럭으로 쌓는다. 쓰레드를 종료하면 런타임 스택도 사라진다.
- PC(Program Counter) 레지스터: 쓰레드 마다 쓰레드 내 현재 실행할 스택 프레임을 가리키는 포인터가 생성된다.
- 네이티브 메소드 스택
- 네이티브 메소드: 메소드에 native 키워드가 붙어 있고, 그 구현이 자바가 아닌 C, C++ 등으로 한 것.
예) Thread.currentThread(); - 네이티브 메소드 라이브러리: 네이티브 메소드의 구현체. 항상 사용은 JNI 를 통해서 사용한다.
- 네이티브 메소드: 메소드에 native 키워드가 붙어 있고, 그 구현이 자바가 아닌 C, C++ 등으로 한 것.
3.실행 엔진 (Execution Engine)
클래스를 실행시키는 역할이다.
클래스 로더가 JVM내의 런타임 데이터 영역에 바이트 코드를 배치시키고, 이것은 실행 엔진에 의해 실행된다.
자바 바이트 코드(*.class)는 기계가 바로 수행할 수 있는 언어보다는 비교적 인간이 보기 편한 형태로 기술된 것이다. 그래서 실행 엔진은 이와 같은 바이트 코드를 실제로 JVM 내부에서 기계가 실행할 수 있는 형태로 변경한다.
↳ 인터프리터
바이트 코드를 한줄 씩 컴파일해서 실행.
실행 엔진은 자바 바이트 코드를 명령어 단위로 읽어서 실행한다.
하지만 한 줄씩 수행하기 때문에 느리다는 단점이 있다.
↳ JIT(Just-In-Time)
반복되는 코드를 모두 네이티브 코드로 바꿔둔다.
인터프리터 효율을 높이기 위해, 인터프리터가 반복되는 코드를 발견하면 JIT 컴파일러로
반복되는 코드를 모두 네이티브 코드로 바꿔둔다.
그 다음부터 인터프리터는 네이티브 코드로 컴파일된 코드를 바로 사용한다.
↳ 가비지 콜렉터 (GC)
더 이상 사용되지 않는 인스턴스를 찾아 메모리에서 삭제함.
'개-발 > 이론' 카테고리의 다른 글
[CS]쓰레드와 쓰레드 풀 (0) | 2023.05.23 |
---|---|
[CS] HTTP Method 특성 (멱등성, 안정성) (0) | 2023.04.24 |
[CS]웹 브라우저에 URL 입력하면 일어나는 일 (0) | 2023.04.14 |
[CS지식] 프로세스 와 스레드 (0) | 2022.11.18 |
[CS지식] CPU (0) | 2022.11.11 |