[자바의 정석]JVM은 무엇이며 자바 코드는 어떻게 실행하는 것인가.

YJS·2023년 11월 6일
0

1. JVM이란 무엇인가


'Java Virtual Machine'을 줄인 것으로 자바를 실행하기 위한 가상 기계. 가상 기계는 소프트웨어로 구현된 하드웨어를 뜻하는 넓은 의미의 용어로 컴퓨터 속의 컴퓨터라고 생각하면 됨. 자바로 작성된 애플리케이션은 모두 JVM에서만 실행되기 때문에 자바 애플리케이션 실행을 위해서는 반드시 JVM이 필요.

Java 애플리케이션 ↔ JVM ↔ OS ↔ 컴퓨터(하드웨어)

  • 자바 애플리케이션은 OS와 하드웨어 독립적
  • JVM은 OS에 종속적
  • Write once, run anywhere이 가능한 이유

2. 컴파일하는 방법


cmd에서 자바 컴파일

-class 파일 만들기 $ javac main.java→ 파일 실행$ java main

자바컴파일 과정

  1. JVM 실행되면 OS로부터 프로그램이 필요한 메모리를 할당받음
  2. Javac가 소스파일(.Java)을 읽어들여 바이트코드( → .Class)로 변환

  1. 생성된 자바 바이트 코드 (.class)는 클래스 로더에 의해서 JVM 내로 로드 후 실행 엔진에 의해 기계어로 해석되어 메모리 상(Runtime Data Area)에 배치됨

cf) 실행엔진인 Interpreter와 JIT(Just-In-Time) Compiler의 차이

-Interpreter는 바이트 코드를 한줄씩 읽기 때문에 실행이 느림

-이러한 단점을 보완하기 위해 나온것이 JIT Compiler. 인터프리터 방식으로 실행하다가 적절한 시점에 바이트 코드 전체를 컴파일 하고 더이상 인터프리팅 하지 않고 해당 코드를 직접 실행. JIT Compiler에 의해 해석된 코드는 캐시에 보관하기 때문에 한 번 컴파일 된 후에는 빠르게 수행하는 장점. 하지만 인터프리팅 방식보다는 훨씬 오래 걸림

→한번만 실행하면 되는 코드는 인터프리팅하는것이 유리.

3. 실행하는 방법


java.exe 파일을 사용하여 컴파일된 .class 파일을 실행

4. 바이트코드란 무엇인가


바이트코드란 JVM이 이해할 수 있는 기계어. JVM이 바이트코드를 해당 OS의 기계어로 변환하여 전달.

cf. 바이너리코드, 기계어, 바이트코드의 차이

바이너리코드: 0과 1로 이루어진 이진코드.

기계어: 컴퓨터가 이해할 수 있는 0과 1로 이루어진 바이너리코드. (단, 기계어 ≠ 바이너리 코드)

기계어가 바이너리 코드로 이루어진 것이지 모든 이진코드가 기계어는 아님.

바이트코드: 가상 머신이 이해할 수 있는 언어

(고급 언어로 작성된 소스코드를 가상머신이 이해할 수 중간코드로 컴파일한 것.)

5. JIT컴파일러란 무엇이며 어떻게 동작하는가


JIT 컴파일 (just-in-time-compilation) 또는 동적 번역(dynamic translation): 프로그램을 실제 실행하는 시점에 기계어로 번역하는 컴파일 기법.

전통적인 입장에서 컴퓨터 프로그램을 만드는 두가지 방법:

  • 인터프리트 방식: 실행 중 프로그래밍 언어를 읽어가면서 해당 기능에 대응하는 기계어 코드를 실행
  • 정적 컴파일 방식: 실행하기 전에 프로그램 코드를 기계어로 번역

JIT 컴파일러는 두가지의 방식을 혼합한 방식. 실행 시점에서 인터프리트 방식으로 기계어 코드를 생성하면서 그 코드를 캐싱하여, 같은 함수가 여러번 불릴 때 매번 기계어 코드를 생성하는 것을 방지.

최근에 자바 가상 머신과 .NET, V8(node)에서는 JIT 컴파일을 지원. 즉, 자바 컴파일러가 자바 프로그램 코드를 바이트 코드로 변환한 다음, 실제 바이트 코드를 실행하는 시점에서 자바 가상 머신이 바이트 코드를 JIT 컴파일을 통해 기계어로 번역. 프로그램이 시작되고 코드를 컴파일한 후에 JIT 컴파일러를 실행함.

6. JVM 구성요소


1) Java Compiler

java source(.java)파일은 ByteCode(.class)로 변환

2) Class Loader

변환된 ByteCode(.class)파일을 JVM이 운영체제로 부터 할당 받은 메모리 영역인 Runtime Data Area로 적재하는 역할

3) Execution Engine

Class Loader 를 통해 JVM 내부로 넘어와 Runtime Data Area(JVM 메모리)에 배치된 ByteCode들을 기계어로 변환(인터프리터, JIT 컴파일러)

cf. GC (Garbage Collection)

자바에서 개발자는 힙을 사용할 수 있는 만큼 자유롭게 사용하고, 더이상 사용되지 않는 오브젝트들은 GC에 의해 자동으로 메모리에서 제거

4) Runtime Data Area

프로그램을 수행하기 위해 운영체제로부터 할당받은 메모리 공간

1. PC Register

Thread가 시작될 때 생성되는 공간으로 Thread마다 하나씩 존재.Thread가 어떤 부분을 어떤 명령으로 실행해야 할 지에 대한 기록을 하는 부분

2. Stack Area

프로그램 실행과정에서 임시로 할당되었다가 메소드를 빠져나가면 바로 소멸되는 특성의 데이터를 저장하기 위한 영역

Stack 영역은 Thread별로 각각 독립적으로 생성. 각종 형태의 변수나 임시데이터, 스레드나 메소드의 정보를 저장. 호출된 메서드의 매개변수, 지역변수, 리턴 값 및 연산 시 일어나는 값들을 임시로 저장.

3. Heap Area

new 연산자로 생성된 객체와 배열을 저장하는 메모리 공간

4. Native method stack

Java가 아닌 다른 언어로 작성된 코드를 위한 공간.자바 프로그램이 컴파일되어 생성되는 바이트 코드가 아닌 실제 수행할 수 있는 기계어로 작성된 프로그램을 실행 시키는 영역

5. Method Area

클래스와 인터페이스의 정보를 처음 메모리 공간에 올릴 때 초기화 되는 대상을 저장하기 위한 메모리 공간.Method Area는 모든 Thread에 의해 공유되는 영역이며, JVM이 시작될 때 생성.

cf. 런타임 상수풀(runtime constant pool), Field, Method, constructor 등 클래스와 인터페이스와 관련된 데이터들을 분류하고 저장한다.

7. JDK와 JRE의 차이


JDK(Java Development Kit): 자바개발도구. 자바 프로그래밍을 위해 필요한 프로그램을 설치.

-javac. exe: 자바 컴파일러. 자바소스코드를 바이트코드로 컴파일.

-java.exe: 자바 인터프리터. 컴파일러가 생성한 바이트코드를 해석하고 실행.

-javap.exe: 역어셈블러. 컴파일된 클래스파일을 원래의 소스로 변환.

-javadoc.exe: 자동문서생성기. 소스파일에 있는 주석을 이용하여 Java API문서와 같은 형식의 문서를 자동 생성.

-jar.exe: 압축프로그램. 클래스파일과 프로그램 실행에 관련된 파일을 하나의 jar파일로 압축하거나 압축해제.

JRE(Java Runtime Environment): 자바실행환경. 자바로 작성된 응용프로그램이 실행되기 위한 최소 환경.

java.exe 파일을 사용하여 컴파일된 .class 파일을 실행

profile
우당탕탕 개발 일기

0개의 댓글