(백기선 라이브 스터디)
목표
자바 소스 파일(.java)을 JVM으로 실행하는 과정 이해하기.
학습할 것
- JVM이란 무엇인가
- 컴파일 하는 방법
- 실행하는 방법
- 바이트코드란 무엇인가
- JIT 컴파일러란 무엇이며 어떻게 동작하는지
- JVM 구성 요소
- JDK와 JRE의 차이
1. JVM이란 무엇인가
JVM은 'java virtual machine'을 줄인 것으로 '자바를 실행하기 위한 가상 머신'이라고 할 수 있다.
Java 애플리케이션은 JVM하고만 상호 작용을 하기 때문에 OS와 하드웨어에 독립적이라 다른 OS에서도 프로그램의 변경 없이 실행이 가능하다. 단 JVM은 OS에 종속적이기 때문에 해당 OS에서 실행 가능한 JVM이 필요하다.(OS에 따라 네이티브 코드로 바꿔야 하기 때문이다.)
JVM에서는 인터프리터와 JIT컴파일러를 통해 자바 바이트 코드(.class 파일)를 OS에 특화된 코드로 변환하거나, 메모리를 할당/해제, 클래스 로딩 등 여러 가지 작업을 진행한다.
JVM은 밴더에 따라 구현이 다르다. ex) 오라클, 아마존, Azul, Red Hat 등등 (가장 많이 사용하는 것은 Oracle Corporation이 소유하고 제공하는 HotSpot )
2. 컴파일 하는 방법 / 3. 실행하는 방법
컴파일이란 우리가 작성한 코드를 바이트코드로 번역하는 과정입니다.
.java 파일의 코드를 작성하면 JVM은 .class파일을 생성한다. 최종적으로. class파일을 자바 인터프리터 실행하면 된다.
> 해당 디렉터리로 이동하여
> javac Hello.java 를 실행한다.
> Hello.class 생성
> java Hello를 실행
public static void main(String[] args)는 main메서드의 선언부인데, java.exe에 의해 호출될 수 있도록 항상 똑같이 정의돼야 한다.
역 컴파일 : 컴파일된 클래스 파일을(.class) -> 다시 자바 파일(. java) 파일로 변환하는 과정이다.
4. 바이트코드란 무엇인가
자바 바이트 코드(Java bytecode)란 자바 가상 머신이 이해할 수 있는 언어로 변환된 자바 소스 코드를 의미합니다.
자바 컴파일러에 의해 변환되는 코드의 명령어 크기가 1바이트라서 자바 바이트 코드라고 불리고 있습니다.
이러한 자바 바이트 코드의 확장자는 .class입니다.
자바 바이트 코드는 자바 가상 머신만 설치되어 있으면, 어떤 운영체제에서라도 실행될 수 있습니다.
5. JIT 컴파일러란 무엇이며 어떻게 동작하는지
JIT (Just-In-Time) 컴파일러는 런타임 시 Java 애플리케이션의 성능을 향상시키는 Java Runtime Environment의 구성 요소입니다. Java 바이트코드는 인터프리트 되지만 JVM의 호스트 CPU에서 원시 코드를 직접 실행하는 것만큼 빠르지 않습니다. 이러한 문제를 해결하기 위해 JIT 컴파일러가 등장했습니다.
JIT 컴파일러는 런타임에 바이트 코드를 원시 기계 코드로 컴파일하여 Java 프로그램의 성능을 향상시킵니다.
인터프리터가 반복되는 코드를 발견하면 JIT 컴파일러로 반복되는 코드를 모두 네이티브 코드로 바꿔둡니다. 그다음부터 인터프리터는 네이티브 코드로 컴파일된 코드를 바로 사용합니다.
6. JVM 구성 요소
1) 클래스 로더 시스템
• 클래스 로더 시스템에서는 3가지 주요 활동을 한다. 로딩, 링킹, 초기화
• 로딩 : 클래스 로더는. class file을 읽고 그에 상응하는 바이너리 데이터를 생성하고, 메소드영역에 저장한다.
• 링킹 : 레퍼런스를 연결하는 과정
• 초기화 : static 값들 초기화 및 변수에 할당
2) 메모리
• 메소드 영역 : 메소드 영역에서는 클래스 수준의 정보들 예를 들면 클래스 이름, 부모 클래스 이름, 메소드, 변수 정보, 정적 변수 등을 저장한다. 이 영역은 공유 자원 영역이다.
• 힙 영역 : 모든 객체 정보가 저장되며 역시 공유 자원 영역이다.
• 스택 영역 : 쓰레드마다 런타임 스택을 만들고, 그 안에 메서드 콜을 스택 프레임이라고 부르는 블럭으로 쌓는다. (에러 메시지가 스택으로 쌓이는 것과 같음)
• PC 레지스터 : 현재 실행 중인 스레드 주소를 저장한다. 각각의 스레드는 분리된 PC 레지스터를 갖고 있다.
• 네이티브 메소드 스택 : 모든 스레드는 분리된 네이티브 메소드 스택이 생성된다.
∘ 네이티브 메소드란 : 메소드에 native라는 키워드가 붙어 있고 그 구현을 c나 c++이 함(ex hread.currentThread(); 라는 메소드)
3) 실행 엔진
실행 엔진은 .class파일(바이트 코드)을 실행한다. 실행엔진은 코드를 line by line 단위로 읽고, 데이터와 정보를 다양한 메소드영역에서 사용하고 실행한다. 이 영역은 3가지 부분으로 나눌 수 있다.
인터프리터 : 코드를 line by line으로 실행
Just-in-Time Compiler (JIT) : 인터프리터 효율을 높이기 위해, 인터프리터가 반복되는 코드를 발견하면 JIT 컴파일러로 반복되는 코드를 모두 네이티브 코드로 바꿔둔다. 그다음부터 인터프리터는 네이티브 코드로 컴파일된 코드를 바로 사용한다.
Garbage Collector (GC) : 더 이상 참조되지 않는 객체를 모아서 정리한다.
- 가비지 컬렉터 종류로는 Serial Collector, Parallel Collector, G1 Collector 등이 있다.
4) JNI(Java Native Interface)
자바 애플리케이션에서 C, C++, 어셈블리로 작성된 함수를 사용할 수 있는 방법을 제공하는 인터페이스이다.
5) 네이티브 메소드 라이브러리
실행 엔진이 필요로 하는 C, C++로 작성된 라이브러리들의 모음이다.
7. JDK와 JRE의 차이
JRE (Java Runtime Environment) : JVM + 라이브러리
• 자바 애플리케이션을 실행할 수 있도록 구성된 배포판.
• JVM과 핵심 라이브러리 및 자바 런타임 환경에서 사용하는 프로퍼티 세팅이나 리소스 파일을 가지고 있다.
• 개발 관련 도구는 포함하지 않는다. (그건 JDK에서 제공 -> javac 같은 것들은 JDK에 있다)
JDK (Java Development Kit) : JRE + 개발 툴
• JRE + 개발에 필요할 툴
• 소스 코드를 작성할 때 사용하는 자바 언어는 플랫폼에 독립적.
• 오라클은 자바 11부터는 JDK만 제공하며 JRE를 따로 제공하지 않는다. (자바 9부터 모듈 링크 jlink제공 : JRE를 사용자 설정으로 만들 수 있다.)
JVM, JDK 및 JRE 비교
JVM은 가상 엔진이며 바이트 코드 지원을 가능하게 하는 엔진입니다.
JRE에는 JVM 및 Java 애플리케이션을 실행하기 위한 기타 모든 라이브러리가 포함되어 있다.
JDK는 JVM, JRE 및 Java 애플리케이션 개발 도구로 구성된 수퍼 세트입니다. 기본 목표는 빌드 및 컴파일을 지원하는 것입니다.
출처
> 자바의 정석
> 백기선, 더 자바를 조작하는 다양한 방법(인프런)
> tcpschool.com/java/java_intro_programming
> aboullaite.me/understanding-jit-compiler-just-in-time-compiler/
> blog.jamesdbloom.com/JVMInternals.html#jit_compilation
'Java' 카테고리의 다른 글
3주차 과제: 연산자 (0) | 2020.11.26 |
---|---|
2주차 과제: 자바 데이터 타입, 변수 그리고 배열(피드백, feedback) (0) | 2020.11.22 |
2주차 과제: 자바 데이터 타입, 변수 그리고 배열 (0) | 2020.11.18 |
1주차 과제: JVM은 무엇이며 자바 코드는 어떻게 실행하는 것인가.(피드백 feedback) (0) | 2020.11.15 |
[java] 깊은 복사(Deep Copy) vs 얕은 복사(Shallow Copy) (0) | 2020.02.09 |