똑같은 삽질은 2번 하지 말자
JVM은 무엇이며 자바 코드는 어떻게 실행하는 것인가 본문
TODOLISTS
- JVM이란 무엇인가
- 컴파일 하는 방법
- 실행하는 방법
- 바이트코드란 무엇인가
- JIT 컴파일러란 무엇이며 어떻게 동작하는지
- JVM 구성 요소
- JDK와 JRE의 차이
JVM 이란 ?
Java Virtual Machine 말 그대로 자바 가상 머신으로써 자바 바이트 코드를 운영체제에 특화된 기계어로 변환시키는
표준이자 구현체이다. (바이트 코드가 무엇인지는 .java 코드가 컴파일하고 실행되는 과정에서 설명!)
자! JVM은 그럼 우리가 자바를 사용할 때 어디에 있는 걸까?
그림을 보면 JVM은 JRE(Java Runtime Enviroment) 안에 있는걸 알 수 있는데 그럼 JRE, JDK에 대해 간단하게 알아보자
JRE (Java Runtime Environment): JVM + 라이브러리
-
자바 애플리케이션을 실행할 수 있도록 구성된 배포판.
-
JVM과 핵심 라이브러리 및 자바 런타임 환경에서 사용하는 프로퍼티 세팅이나 리소스 파일을 가지고 있다.
-
개발 관련 도구는 포함하지 않는다. (그건 JDK에서 제공)
JDK (Java Development Kit): JRE + 개발 툴
-
JRE + 개발에 필요할 툴
-
소스 코드를 작성할 때 사용하는 자바 언어는 플랫폼에 독립적.
-
오라클은 자바 11부터는 JDK만 제공하며 JRE를 따로 제공하지 않는다.
-
Write Once Run Anywhere
이렇게 JVM이 어디에 있는지도 알게되었고 그럼 JVM의 역할로써
자바 바이트 코드를 운영체제에 특화된 기계어로 변환? 을 어떻게 하고 있는걸까?
본격적으로 파고 들어가기 전에 JVM 구조를 한번 보고 가자.
Classloader
클래스 파일을 읽어들여서 메모리에 저장을 하는 친구다.
ClassLoader WorkFlow: 로딩 -> 링크 -> 초기화
- 로딩 : 실제 클래스 파일을 읽고 그 내용에 따라 적절한 바이너리 데이터를 만들고 "메소드"에 영역에 저장로딩이 끝나면 해당 클래스 타입의 Class 객체를 생성하여 힙 영역에 저장한다.
- 링크 : 클래스파일 형식이 유효한지 체크(Vertify) -> 클래스 변수와 기본값(static 변수)에 필요한 메모리를 준비(Preparation) -> 심볼릭 메모리 래퍼런스를 메소드 영역에 있는 실제 레퍼런스로 교체한다(Resolve)
- 초기화 : static 값의 초기화 및 변수에 할당
Class(Method) Area
클래스 영역에는 클래스 수준의 정보들이 저장되는데, 클래스 이름, 메소드, 변수, 상속받은 클래스 이름 등등이
저장되며 공유되는 정보들이다.
Heap
힙영역에는 실제로 만들어진 객체(인스턴스)가 저장되는 공간
Stack
스택은 스택 프레임을 저장하며, 로컬 변수와 부분 결과를 저장하고 메소드 호출 및 반환에 대한 역할을 수행한다.
각 스레드는 스레드와 동시에 생성되는 전용 JVM 스택을 가집니다. 즉, 스레드마다 런타임 스택을 가지고 있다는 것.
메소드가 호출될 때마다 새 프레임이 생성되며. 메서드 호출이 완료되면 프레임이 소멸된다.
Program Counter Register
PC는 현재 실행 중인 Java 가상 시스템 명령의 주소가 포함되어 있다.
스레드 마다 스레드 내 현재 실행할 스택 프레임을 가리키고 있다고 보면 될 것 같다.
Native Method Stack
Application에서 사용되는 네이티브 메소드가 들어있는 공간
Execution Engine
- A virtual processor
- Interpreter: 바이트 코드를 한줄씩 읽어들여 실행
- Just-In-Time(JIT) compiler: JIT은 인터프리터의 성능향상을 위해 사용되어 진다. JIT은 기능이 유사한 바이트 코드의 일부를 동시에 컴파일해서 모두 네이트브 코드로 바꿔둔 뒤, 그 다음부터 인터프리터는 네이티브 코드로 컴파일된 코드를 바로 사용한다.
Java Native Interface
JNI는 C, C++, Assembly 등과 같은 다른 언어로 작성된 다른 응용 프로그램과 통신하기 위한 인터페이스를 제공하는 프레임워크다. Java는 JNI 프레임워크를 사용하여 출력을 콘솔로 전송하거나 OS 라이브러리와 상호 작용합니다.
JVM의 구성요소를 보면서 .class 코드(바이트 코드)를 읽고 그걸 어떻게 갖고 노는지가 어느정도 윤곽이 잡혔지만,
애초에 바이트 코드는 무엇이며 어떻게 만들어지는 걸까?
쉬운 이해를 위해 전체적인 흐름이 있는 사진을 가져와 보았다.
그림을 보면 Java Compiler로 .java -> .class 파일로 변환시키고 있는걸 볼 수 있다.
(터미널에서 $javac test.java -> test.class(컴파일) / $java test.class(실행) -> 실행결과)
자바에 있어서 바이트 코드란 .class파일이며 이것은 JVM이 다루는 코드 ,즉 JVM이 인식하기 쉬운 코드 인것이다.
왜 이렇게 바이트 코드로 변환해서 넘겨주냐? 라고 하면 우리가 개 같이 작성한 코드들을 아무래도
JVM 입장에서는 도저히 눈 뜨고 볼 수 없어서 한번 필터링을 거쳐가는거라고 이해하는 편이 좋을 것 같다.
'STUDY HALLE > 과제' 카테고리의 다른 글
연산자 (0) | 2021.01.10 |
---|---|
자바 데이터 타입, 변수 그리고 배열 (0) | 2020.12.30 |