JVM이란 무엇인가
- Java Virtual Machine의 약어
- 자바가상머신이라고도 불린다.
- 자바 프로그램을 컴파일 해서 나온 결과인 바이트코드를 실행시켜주는 가상 머신이다.
- 각 운영체제별 JVM은 자바측에서 개발하여 배포하므로, 프로그래머는 운영체제에 관계없이 프로그램을 개발할 수 있어, 한번 컴파일 됐으면 운영체제에 따라 다시 컴파일할 필요가 없는 WORA(Write Once Run Anywhere)를 만족한다.
자바 소스파일(.java)을 JVM으로 실행 과정
1) 프로그램이 실행되면 JVM은 운영체제로 부터 이 프로그램이 필요로 하는 메모리를 할당 받음
JVM은 이 메모리를 용도에 따라 여러 영역으로 나누어 관리
2) 자바 컴파일러(javac)가 자바 소스코드(.java)를 읽어들여 자바 바이트코드(.class)로 변환
.java -> .class
3) Class Loader를 통해 class파일을 JVM 메모리에 적재
4) JVM 메모리 영역에 적재된 class 파일을 Execution engine을 통해 해석
컴파일 하는 방법
컴파일이란 우리의 언어는 컴퓨터가 이해하지 못하므로 컴퓨터가 이해할 수 있도록 "통역"하는 작업을 말한다.
1. 자바 컴파일러는 자바 개발 키트(JDK)에 포함되어 있기 때문에 작성된 코드를 컴파일해 바이트코드를 생성하기 위해선 우선 JDK가 필요하다.
2. 자바 언어 사양(JLS)을 충족하는 자바 소스코드(*.java) 파일을 작성한다.
3. 자바 컴파일러(javac.exe)를 통해 자바 소스코드(.java)를 자바 가상 머신 사양(JVMS)을 충족하는 바이트코드(.class)로 컴파일 한다.
- javac Test.java
4. *.class 파일이 생성된 것을 확인 할 수 있다.
- Test.class
실행하는 방법
java.exe -> 자바 인터프리터로서 컴파일러로 생성된 바이트 코드를 해석하고 실행한다.
- java Test
바이트코드란 무엇인가
프로그램을 실행하는 것은 결국 컴퓨터이다. 다시 말해 프로그램은 컴퓨터가 이해할 수 있는 형태로 작성되어 있어야 한다.
1) 바이너리코드란?
C언어는 컴파일러에 의해 소스파일(.c)이 목적파일(.obj)로 변환될 때 0과 1로 이루어진 바이너리코드로 변환된다.
즉, 컴파일 후에 이미 컴퓨터가 이해할 수 있는 이진코드로 변환되는 것이다.
목적파일은 기본적으로 컴퓨터가 이해할 수 있는 바이너리코드의 형태이지만 실행될 수는 없다. 그 이유는 완전한 기계어가 아니기 때문 (변화된 목적 파일은 링커에 의해 실행 가능한 실행파일(.ex)로 변환 될 때 100% 기계어가 될 수 있다.
2) 기계어란 ?
기계어는 컴퓨터가 이해할수 있는 0과 1로 이루어진 바이너리코드이다.
기계어가 바이너리코드로 이루어졌을 뿐이지 모든 이진코드가 기계어인 것은 아니다( 바이너리코드 != 기계어)
3) 바이트코드란 ?
c언어와 다르게 Java에서는 컴파일러(javac)에 의해 소스파일(.java)이 컴퓨터가 바로 인식할 수 없는 바이트코드(.class)로 변환된다.
컴퓨터가 이해할 수 있는 언어가 바이너리코드라면 바이트코드는 가상 머신이 이해할 수 있는 언어이다.
고급언어로 작성된 소스코드를 가상 머신이 이해할 수 있는 중간 코드로 컴파일한 것을 말한다.
이러한 과정을 거치는 이유는 어떠한 플랫폼에도 종속되지 않고 JVM에 의해 실행 될수 있도록 하기 위함이다.
여기서 플랫폼이란 개발환경 실행환경 등 어떠한 목적을 수행할 수 있는 환경을 말한다.
ex) 프로그램이 실행되는 환경인 운영체제의 종류(window, mac), 개발이 수행되는 환경의 종류(안드로이드, 비주얼 스튜디오)
JIT 컴파일러란 무엇이며 어떻게 동작하는지
JIT 컴파일러란 무엇이며 어떻게 동작하는가?JIT 컴파일러란? 기존 클래스파일(바이트코드)를 실행하는 방법은 Interpreter 방식이 기본이다. Interpreter 방식은 3-1에서 설명한바와 같이 명령어를 하나씩 해석해서 처리하는 개념이기 때문에 명령어 하나하나 실행하는 속도는 빠를지 모르나 전체 코드 관점에서 보면 실행 속도가 느린 단점이 있다. 해당 문제를 해결하기 위해서 나온 방법이 JIT 컴파일러이고 JIT 컴파일러는 런타임 시 클래스파일(바이트코드)를 네이티브 기계어로 한방에 컴파일 후 사용하는 개념으로 이해하는 것이 편하다.
좀 더 상세히 얘기하자면 전체 컴파일 후 캐싱 -> 이후 변경된 부분만 컴파일하고 나머지는 캐시에서 가져다가 바로 실행 이다. 바로 꺼내서 사용하고 변경 부분만 컴파일 하기 때문에 코드 수행속도가 Interpreter 방식에 비해서 빠르다!
JVM 구성 요소

출처: https://www.guru99.com/images/1/2.png
6-1. Class Loader: 클래스 로더는 클래스 파일을 로드하는 데 사용되는 하위 시스템이다.
6-2. Method Area: JVM Method Area는 메타데이터, 상수 런타임 풀, 메서드에 대한 코드와 같은 클래스 구조를 저장한다. 공유자원(여기서 공유자원이라는 의미는 다른 스레드에서도 활용 가능한 자원을 말함)이다.
6-3. Heap: 모든 개체, 관련 인스턴스 변수 및 배열은 힙에 저장된다.
이 메모리는 여러 스레드에 걸쳐 공유된다.
6-4. JVM Language Stacks: Java Language Stacks는 로컬 변수를 저장하고 부분적인 결과를 얻는다.
각 스레드에는 자체 JVM 스택이 있으며, 스레드가 생성될 때 동시에 생성된다.
메서드를 호출할 때마다 새 프레임이 생성되고, 메서드 호출 프로세스가 완료되면 삭제된다.
스택은 공유자원이 아니므로 스레드 세이프(여러 스레드에서 공용 자원을 접근할 때 생길 수 있는 문제) 하다.
내부에는 Local Variable Array, Operand Stack, Frame Data의 영역이 있다.
6-5. PC Register: PC 레지스터는 현재 실행 중인 Java 가상 시스템 명령의 주소를 저장한다.
자바에서는 각 스레드에 별도의 PC 레지스터가 있다.
6-6. Native Method Stack: 네이티브 메서드 스택은 네이티브 라이브러리에 따라 네이티브 코드 명령을 보관한다.
자바 대신 다른 언어로 쓰여 있다.
6-7. Execution Engine: 런타임 데이터 영역에 할당 된 바이트코드는 실행 엔진에 의해 실행된다.
실행 엔진은 바이트코드를 읽고 조각 별로 실행한다.
6-8. Native Method Interface: Native Method Interface는 프로그래밍 프레임워크다. JVM에서 실행 중인 Java 코드가 라이브러리 및 네이티브 애플리케이션으로 호출할 수 있도록 한다.
6-9. Native Method Libraries: Native Libraries는 실행 엔진에 필요한 Native Libraries(C, C++)의 모음이다.
JDK와 JRE의 차이
JRE
- Java Runtime Environment의 약자로, 자바 실행 환경을 의미한다.
- JVM을 동작하는데에 필요한 각종 자바 라이브러리를 담고 있다.
JDK
- Java Development Kit의 약자로, 자바 개발 키트를 의미한다.
- JRE와 javac 등의 컴파일러, 디버거등을 포함하는 프로그램이다.
- 오라클사에서 제공하는 오라클 JDK와 오픈소스로 개발된 OpenJDK가 있으나, 일반적으로 사용되는것은 오라클 JDK이다.
'Language > Java' 카테고리의 다른 글
| [6주차] 상속 (0) | 2022.01.30 |
|---|---|
| [5주차] 클래스, [7주차] 패키지 (0) | 2022.01.22 |
| [4주차] 과제 (0) | 2022.01.16 |
| [4주차] 제어문 (0) | 2022.01.10 |
| [2주차] 자바 데이터 타입, 변수 그리고 배열 (0) | 2022.01.02 |