1주차 과제: JVM은 무엇이며 자바 코드는 어떻게 실행하는 것인가.

2020. 11. 14. 02:55
728x90

목표

자바 소스 파일(.java)을 JVM으로 실행하는 과정 이해하기.

학습할 것

  • JVM이란 무엇인가
  • 컴파일 하는 방법
  • 실행하는 방법
  • 바이트코드란 무엇인가
  • JIT 컴파일러란 무엇이며 어떻게 동작하는지
  • JVM 구성 요소
  • JDK와 JRE의 차이

 JVM이란 무엇인가 

 

 

  •    자바가상머신(Java Virtual Machine, JVM)은 바이트코드(.class)를 실행할 수 있는 주체
  •    자바 코드를 컴파일 해서 얻은 바이트코드를 해당 운영체제가 이해할 수 있는 기계어로 바꿔 실행시켜주는 역할
  •    자바로 작성된 애플리케이션은 모두 JVM에서만 실행되기 때문에 반드시 JVM이 필요하다.
  •    자바 프로그램이 어느 운영체제에서도 실행될 수 있게 프로그램 메모리를 관리하고 최적화해준다.
  •    한번만 프로그램을 작성하면 모든 운영체제에서 사용할 수 있다.
  •    운영체제에 종속적이므로 각 운영체제에 맞는 가상머신을 설치해야한다.
  •    자바 프로그램은 JVM을 한번 더 거치지 때문에 실행속도가 느리다.

 

 

 JVM의 구성요소

 

 

- 실행될 .class파일을 메모리에 로드 후 초기화 작업 수행.

- 메소드와 클래스 변수들을 해당 메모리영역에 배치한다.

- 클래스로드가 끝난 후 JVM은 main()메소드를 찾아 지역변수, 객체변수, 참조변수를 스택에 쌓는다.

 

 

Class Loader

 

  • 자바컴파일러가 .java파일을 컴파일하면 .class파일(자바바이트코드)이 생성된다.
  • 생성된 .class파일들을 엮어 Runtime Data Area 형태로 메모리에 적재하는 역할을 한다.

Class Loader 우선순위

  • Bootstrap > Extention > System

클래스로더가 로드를 요청받으면, 클래스 로더 캐시 상위 클래스 로더 자기 자신 순서로 클래스가 있는지 확인한다

부트 스트랩 클래스로더까지 확인해도 없으면 요청받은 클래스 로더가 파일 시스템에서 해당 클래스를 찾는다.

 

1) BootStrap ClassLoader

  • JVM이 실행될때 가장 먼저 실행되는 클래스 로더로, 자바 실행에 필요한 기본적은 클래스를 로딩한다.
  • 다른 클래스로더와 달리 네이티브 코드로 구현되어 있다.

2) Extention ClassLoader

  • 추가로 로딩되는 클래스로더로 별도로 클래스패스에 설정되어 있지 않아도 로딩된다.
  • 다양한 보안 확장 기능을 여기서 로드한다.

3) System ClassLoader

  • ClassPath에 정의 되어 있거나 JVM옵션에서 -cp, -classpath에 지정된 클래스들이 로딩된다.
  • 시스템 클래스로더는 애플리케이션의 클래스들을 로드한다고 할 수 있다.
  • 즉 사용자가 지정한 $CLASSPATH내의 클래스가 로드된다.

4) User-Defined Class Loader

  • 애플리케이션 사용자가 직접 코드 상에서 사용하는 클래스 로더이다.
  • 일반적으로 Jar 혹은 WebApp의 경우 War로 압축된 ClassPath의 Binary Code를 사용자 정의 클래스 로더가 로드한다.

 

 

클래스 로더가 로드하지 않은 클래스를 찾으면 다음과 같이 로드하고 링크하며 초기화한다.

 

  1.  로드 :  찾은 클래스 파일을 Runtime Data Area에 로드한다.
  2.  검증 : 읽어 들인 클래스가 제대로 구성되어 있는지 검사. 클래스 로드 전 과정 중 가장 시간이 오래 걸리며 까다로운 검증을 거침.
  3.  준비 : 클래스가 필요로 하는 메모리를 할당하고, 클래스에 정의된 필드, 메소드, 인터페이스들을 나타내는 데이터 구조를 준비한다.
  4.  분석 :  클래스의 상수 풀 내 모든 심볼릭 레퍼런스를 다이렉트 레퍼런스로 변경.                                                                                       (심볼릭 레퍼런스는 메모리번지의 참조를 의미하는 것이 아니라 이름에 의한 참조를 의미)
  5.  초기화 : 클래스 변수들을 적절한 값으로 초기화 한다.

 

 

Execution Engine

  • Class Loader에 의해 메모리에 적재된 클래스(바이트코드)들을 기계어로 변경해 명령어 단위로 실행하는 역할
  • 인터프리터(Interpreter)방식이 있고, JIT(Just-In-Time)컴파일러 방식이 있다

 

 

Garbage Collector (GC)

  • 힙 메모리 영역에 존재하는 객체들 중에 생존 여부를 판단하여 더 이상 사용되지 않는 객체를 제거하는 방식으로 메모리를 자동 관리한다.
  • GC가 역할을 하는 시간은 정확히 언제인지 알 수 없다
  • GC가 수행되는 동안 GC를 수행하는 쓰레드가 아닌 다른 모든 쓰레드가 일시정지된다.

 

 

Runtime Data Area

  • JVM이 운영체제 위에서 실행되면서 할당받는 메모리 영역이다.
  • Class Loader에서 준비한 데이터들을 보관하는 저장소이다.

1. Method area (메소드 영역)

  • 클래스 멤버 변수의 이름, 데이터 타입, 접근 제어자 정보같은 필드 정보와 메소드의 이름, 리턴 타입, 파라미터, 접근 제어자 정보같은 메소드 정보, Type정보(Interface인지 class인지), Constant Pool(상수 풀 : 문자 상수, 타입, 필드, 객체 참조가 저장됨), static 변수, final class 변수등이 생성되는 영역이다.

 

2. Heap area (힙 영역)

  • JVM이 관리하는 프로그램 상에서 데이터를 저장하기 위해 런타임 시 동적으로 할당하여 사용하는 영역이다.
  • new 연산자로 생성된 객체 또는 인스턴스와 배열을 저장한다.
  • 힙 영역에서 생성된 객체와 배열은 스택 영역의 변수나 다른 객체의 필드에서 참조한다.
  • 참조하는 변수나 필드가 없다면 의미 없는 객체가 되어 GC의 대상이 된다.

 

3. Stack area (스택 영역)

 

  • 각 스레드마다 하나씩 존재하며, 스레드가 시작될 때 할당된다.
  • 메소드를 호출할 때마다 프레임(Frame)을 추가(push)하고 메소드가 종료되면 해당 프레임을 제거(pop)하는 동작을 수행한다.
  • FILO (First In Last Out) 구조로 push와 pop 기능 사용
  • 메소드 호출 시 생성되는 스레드 수행정보를 기록하는 Frame을 저장
  • 메소드 정보, 지역변수, 매개변수, 연산 중 발생하는 임시 데이터 저장
  • 기본(Primitive) 타입 변수는 스택 영역에 직접 값을 가진다.
  • 참조 타입 변수는 힙 영역이나 메소드 영역에 Reference를 가진다.
  • 힙 영역에 있는 객체가 스택 영역에서 참조할 수 없는 경우 GC의 대상이 된다.

4. PC Register (PC 레지스터)

  • Thread(쓰레드)가 생성될 때마다 생성되는 영역으로 Program Counter 즉, 현재 쓰레드가 실행되는 부분의 주소와 명령을 저장하고 있는 영역이다. (*CPU의 레지스터와 다름)
  • 스레드가 어떤 명령어로 실행되어야 할지에 대한 기록을 하는 부분으로 현재 수행중인 JVM 명령의 주소를 갖는다.

 

5. Native method stack

  • 자바 외 언어로 작성된 네이티브 코드를 위한 Stack 메모리 영역이다.

 

 

 바이트코드란 무엇인가

 

  • 자바가상머신(JVM)이 이해할 수 있는 언어로 변환된 자바소스코드를 의미함.
  • 자바 컴파일러에 의해 변환되는 코드의 명령어 크기가 1바이트라서 바이트코드라고 불린다.
  • 바이트코드의 확장자는 .class
  • 바이트코드는 인터프리터 방식으로 해석한다.
  • 바이트코드를 생성하는 것까지가 컴파일이고, 바이트코드 자체는 인터프리터언어다.

 

 

 

 

 컴파일 하는 방법  &  실행하는 방법

 

 

컴파일 한다는 것은 자바파일( .java)을  바이트코드( .class)로 변환하는 것을 의미.

빌드 시, 자바파일(.java)을 자바컴파일러 (javac.exe)를 이용하여 JVM이 이해할수 있는 바이트코드(.class)로 바꿔준다.

 

* JDK(Java Development Kit)자바개발도구를 설치하면 bin폴더 안에 javac이라는 java compiler가 포함되어 있다.

*  javac.exe는 JDK, java.exe 는 JRE에 포함되어 있기에 JDK과 JRE를 설치해야 하지만 과거와 다르게 요즘은 JDK에 JRE가     포함된 형태로 배포되고 있기에 JDK만 설치해도 무관하다.

더보기

개발툴을 이용해 자바파일( .java)를 생성

 

 javac 명령어를 이용해 컴파일한다.

$ javac 파일명.java

 

클래스파일( .class)의 생성

 

 

컴파일된 바이트 코드(.class)를 실행할 때 java.exe 사용

$ java 파일명

 

 

 

 

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

 

 

빌드 시, 자바파일(.java)을 자바컴파일러(javac.exe)를 이용하여 JVM이 이해할 수 있는 중간단계의 언어 바이트코드(.class)로 바꿔준다.  런타임 시, 바이트코드를 기계어로 바꿔주는데 이 역할을 JVM에서 한다. ClassLoader를 통해 바이트코드를 JVM내로 로드하고, Runtime Data Areas를 거쳐 Execution Engine으로 간다. Execution Engine에서 바이트코드로 변환하는 두가지 방식이 있는데 인터프리터와 JIT컴파일러(Just-In-Time) 방식이다.

자바 바이트코드는 인터프리터언어이다. 소스코드를 한 문장씩 읽고 기계어로 바꿔주기 때문에 실행속도가 느리다.

이 단점을 보완하기 위해 나온 것이 JIT컴파일러 이다.

 

JIT컴파일러란

  • 프로그램 실행 중에 가상기계상에서만 돌아가는 자바 바이트 코드를 해당 플랫폼에 맞는 기계어로 컴파일 해주는 특수한 컴파일러이다.
  • 인터프리터방식을 사용하다가 적정한 때에 바이트 코드 전체를 기계어로 바꾸는 방식을 가진다. 이때 기계어는 캐싱을 이용하기 때문에 인터프리터의 단점을 극복할 수 있다.

JIT 컴파일러가 바이트코드를 기계어로 컴파일하는 시간만큼 프로그램의 실행시간이 증가하게 된다.

하지만, 만약 매우 복잡하고 다양한 연산들을 하면서 자주 불려지는 메소드를 JIT컴파일러로 컴파일 한다면,

실행능력을 크게 향상시킬 수 있다.

 

JIT컴파일러의 작동

 

JIT컴파일러는 JRE(Java Runtime Environment)의 일부로서 자바 응용프로그램의 성능을 실행시간 중에 향상시켜주는 도구이다.

 

자바프로그램은 다양한 컴퓨터 아키텍처에서 JVM이 해석할 수 있는 플랫폼 중립 바이트코드를 포함하는 클래스로 구성된다.런타임시, JVM은 클래스파일을 로드하고 각 개별 바이트코드의 의미를 결정하고 적절한 계산을 수행한다. 해석 중 추가 프로세서 및 메모리 사용량은 자바 애플리케이션이 원시 애플리케이션보다 느리게 수행됨을 의미한다.JIT컴파일러는 런타임에 바이트코드를 원시기계코드로 컴파일하여 자바 프로그램의 성능을 향상시킨다.JIT컴파일러는 기본적으로 사용가능하며, 자바 메소드가 호출될 때 활성화 된다. JIT컴파일러는 해당 메소드의 바이트코드를 원시기계코드로 컴파일하여 적시에 실행되도록 컴파일한다.메소드가 컴파일되면 JVM은 해석하는 대신 해당 메소드의 컴파일된 코드를 직접 호출한다.이론적으로 컴파일에 프로세서 시간과 메모리 사용이 필요하지 않은 경우, 모든 메소드를 컴파일하면 자바 프로그램의 속도가 네이티브 응용프로그램의 속도에 접근할 수 있다.JIT컴파일에는 프로세서 시간과 메모리 사용량이 필요하다. JVM이 처름 시작되면 수천개의 메소드가 호출되고 이러한 모든 방법을 컴파일하면 프로그램이 결국 매우 우수한 최고 성능을 달성하더라도 시작 시간에 상당한 영향을 미칠 수 있다.

 

 

 JDK 와 JRE의 차이

 

JDK

JDK는 자바 개발도구(Java Development Kit)의 약자이다.

JDK는 JRE 에서 개발을 위해 필요한 도구(javac, java, visualVM 등)들을 포함한다.

 

  • JRE + 개발 툴(java c)
  • 자바 11부터는 JDK 단위로 배포됨.

 

JRE

JRE는 자바 실행환경(Java Runtime Environment)의 약자이다.

JRE는 JVM 이 자바 프로그램을 동작시킬 때 필요한 라이브러리 파일들과 기타 파일들을 가지고 있다. JRE는 JVM의 실행환경을 구현했다고 할 수 있다.

 

  • JVM + 핵심 라이브러리
  • 개발 관련 x. 실행 관련 o
  • java 는 보통 JRE 단위로 배포됨



 참고 

728x90

BELATED ARTICLES

more