본문 바로가기

카테고리 없음

JVM으로 실행하는 과정 이해하기

★ JVM이란 무엇인가?

 

자바 가상머신이라 불리는 JVM(Java Virtual Machine)은 자바와 OS사이의 중개자 역할을 수행하기에 굳이 OS에 구애받지 않고 사용(WORA)할 수 있게 해준다

 

- 애플리케이션에 있어 중요한 요소 메모리 관리 및 GC(Garbage Collection)을 수행한다

   (OS의 level에서 Memory leak을 불가능 하게한다.)

 

운영체제 위에서 동작하는 프로세스이다


- 자바 코드를 컴파일해 얻은 바이트코드를 운영체제가 이해할 수 있는 기계어로 번역한다

 

- 스택기반으로 설계된 가상머신이다.

* 스택기반의 가상머신 vs 레지스터 기반의 가상머신

 

[ 스택 기반 ]


1) 스택기반의 가상머신
- 피연산자와 연산 후 결과를 스택에 저장하는 구조
- 다음 피연산자의 메모리 위치를 기억할 필요가 없이 POP만 하면 다음 피연산자가 나오기 때문에 메모리를 굳이 기억할 필요가 없다.

 

 

[ 레지스터 기반 ]


2) 레지스터 기반의 가상머신
- 피연산자가 CPU의 레지스터에 저장됨
- 명령어가 피여난자의 위치인 레지스터의 주소를 기억해야함
- 스택보다 명령어의 길이가 길고, 피연산자의 주소를 명시해야 하기 때문에 평균적으로 길 수 밖에 없다.

* 자바 애플리케이션이 동작하는 과정

 

1. 프로그램 실행 시 JVM은 운영체제로 부터 메모리를 할당받음(이때 용도에 따라 메모리를 나누어 관리)
2. 자바 컴파일러가 자바 소스코드를 읽어들여 바이트코드로 변환
3. 클래스로더를 통해 JVM의 Runtime Data Area에 로딩
4. 로딩된 바이트 코드들은 execution engine을 통해 해석

   (필요에 따라 JVM은 Thread Synchronization, GC를 통해 관리 작업을 수행)

 

 컴파일 및 실행하는 방법


- 자바를 컴파일 하는 방법은 먼저 자바 소스코드를 작성한다. 

[MainClass 작성]


- javac(자바 컴파일러) 명령어 통해 자바 소스코드를 JVM이 이해할 수 있는 형태로 변환한다.

  (class 파일 생성)


- java 명령어를 통해 해당 class 파일을 실행한다.

 


 바이트 코드란 무엇인가


- JVM이 이해할 수 있는 언어로 변환된 자바 소스 코드를 의미한다.


- javac에 의해 변환되는 코드의 크기가 1바이트이기 때문에 바이트 코드라고 불린다.


- .class의 확장자를 갖고 있다.


JVM만 있으면 어느 운영체제에서든 실행이 가능하다.

 


 JIT 컴파일러(Just-In-Time)


- 인터프리터 방식의 단점을 보완하기 위해 도입

=> 인터프리터 방식으로 동작하다 적절한 시점에 가장 자주 실행되는 영역을 컴파일하여 

     네이티브코드로 변경하고 캐싱한다.
     그 후 더이상 인터프리터 방식을 사용하지 않고, 네이티브 코드를 사용하여 최초 실행은 느릴 수

    있지만, 그 후 실행하는데에 있어 성능을 향상시킬 수 있다.

 

 

JVM의 구성요소 

[ JVM의 구조 ]


1. ClassLoader
=> 자바 소스코드를 컴파일하여 생성된 바이트코드를 엮어 운영체제로 부터 할당받은 메모리 영역

     Runtime Data Area에 적재하는 역할을 수행

2. Execution Engine
=> ClassLoader에 의해 적재된 바이트코드들을 기계어로 해석해 인터프리터 방식으로 수행

3. Garbage Collector
=> Heap 메모리에 생성된 객체 중 참조되지 않은 객체를 탐색 후 제거하고 Garbage Collector가 동작하는 시간은 정확히 언제인지 알 수 없고,
     Garbage Collector가 수행되는 동안 모든 Thread들은 정지 상태가 된다.(Stop the world)

4. Runtime Data Area
=> JVM이 애플리케이션을 실행할 때 사용하는 데이터 적재 공간이다.
1. Method Area : 클래스 파일을 읽어 인스턴스 변수, 메소드 등을 저장하는 공간
2. Heap Area : 객체를 동적으로 생성될 때 할당될 메모리 영역(GC의 대상이 되는 영역)
3. Stack Area : Thread가 생성될때마다 생성되고, Thread내의 메소드 호출 시 Stack 영역에 쌓이게 된다.
==> 멀티 스레드 기반의 애플리케이션의 경우 Thread 마다 고유의 Stack을 갖고있으나, Heap 영역은 공유 하기 때문에 Heap 영역에서 발생할 수 있는 Thread safe의 문제를 주의해야한다.


JDK와 JRE의 차이 


- JDK : Java Development Kit의 약자로 개발도구, JRE와 개발용 라이브러리를 포함하고 있다.


- JRE : Java Runtime Environment의 약자로 자바 프로그램을 실행하기 위한 라이브러리와 파일을 포함하고 있다.