JVM은 무엇이며 자바 코드는 어떻게 실행하는 것인가
목표
자바 소스 파일(.java)을 JVM으로 실행하는 과정 이해하기.
목차
- JVM이란 무엇인가
- 컴파일 하는 방법
- 실행하는 방법
- 바이트코드란 무엇인가
- JIT 컴파일러란 무엇이며 어떻게 동작하는지
- JVM 구성 요소
- JDK와 JRE의 차이
(출처 : https://medium.com/@ahn428/java-jit-%EC%BB%B4%ED%8C%8C%EC%9D%BC%EB%9F%AC-c7d068e29f45)
JVM(Java Virtual Machine)은 운영체제와 자바 프로그램 사이에 존재한다.
운영체제가 JVM을 실행시키고 JVM은 자바 프로그램을 실행시키는 구조이다.
-> 자바프로그램은 왜 운영체제가 직접 실행을 시키는 구조가 아닌, JVM에 의해서 실행되는 구조로 설계한 것일까?
프로그램이라는 것은 운영체제에 따라서 달리 구현된다. 윈도우즈에서 동작하도록 구현된 프로그램은 리눅스 등 다른 운영체제 기반에서 동작되지 않는다. 하지만 JVM이 운영체제에 따른 차이점을 대신 처리해주기 때문에 운영체제에 상관없이 자바프로그램이 실행된다.
JVM이 자바 프로그램을 실행 시킬 때는 자바 소스파일 원본으로 실행시키는 것이 아니라 컴파일러에 의해 생성된 바이트코드로 실행한다.
JVM의 가비지 컬렉션
JVM의 구성요소에 가비지 컬렉션(Garbage Collection)이 있는데, 이것은 클래스 인스턴스를 사용자 코드에 의해 명시적으로 생성하고 가비지 컬렉션에 의해 자동으로 삭제되게 만들어서 메모리 관리를 효율적으로 한다.
이는 'javac'라는 자바 컴파일러에게 'Test_Java' 라는 소스파일을 컴파일을 요청하는 문장이다.
'javac.exe' 파일을 실행함으로써 자바 소스파일을 바이트코드로 컴파일한다.
'java' 명령어로 실행한다.
->"java Test_Java"를 입력한다.
이는 'java.exe'라는 자바 런처 파일에게 'Test_Java'의 실행을 요청하는 문장이다.
'java.exe' 파일은 자바 가상머신을 구동시키고 그 위에 자바 프로그램이 실행되도록 돕는 프로그램이다.
위에서 자바의 소스코드가 'javac'에 의해서 컴파일된 파일이 'java'에 의해서 가상머신을 기반으로 실행이 되는 구조다.
(출처 : https://neos518.tistory.com/93)
직역하면 어떤 시점에 즉시 컴파일을 함. -> 코드를 실행하는 시점에서 즉시 컴파일을 한다는 뜻
JRE (Java runtime environment)의 일부이다.
자바 가상 머신이 바이트코드를 기계어로 바꿔서 운영체제에 실행시키는 방법으로 사용함.
-> 다른 컴파일러와 다른점은?
가장 큰 차이점은 코드를 실행할 때 컴파일 한다는 것이다.
기존의 컴파일된 프로그램은 실행하려는 운영체제에게 강한 영향을 받는다.
만약 윈도우에서 컴파일을 했다면 이 프로그램을 똑같이 리눅스에서 쓸 수 없다.
그래서 JIT가 중간에서 바이트코드를 기계어로 변환할 때 플랫폼에 맞게 변경해주는 방식으로 해결한다.
(이것이 위에 '1.' 에서 언급했던 JVM이 운영체제에 상관 없이 동작할 수 있게 만든 방식인 것 같다.)
바이트 코드를 기계어로 변환 시킬 때, 반복되는 메소드를 캐싱한다. 그 반복된 메소드가 또 사용될때 캐싱해둔 코드를 사용하여 실행속도를 높이는 것이다.
그렇기 때문에 반복적인 메소드가 많은 코드를 컴파일 할 때 좋은 효과를 발휘할 수 있다.
(객체지향의 특성을 고려햐여 설계한 것 같은 생각이 든다.)
(출처 : https://blog.naver.com/jjekjjek7/222038511893)
Class Loader
자바 소스파일이 바이트코드로 파일일 된 것을 Runtime Data Area에 로딩 시키는 역할을 한다.
Runtime Data Area
JVM이 프로그램을 실행할 수 있도록 OS로부터 할당 받은 메모리 공간이다.
이 영역은 Method Area, Heap Area, Stack Area, PC register, Native Method Stack으로 구성되어 있다.
[Method Area]
클래스 로더에 의해 로딩된 바이트코드의 내용을 분석하여 저장한다.
[Heap Area]
객체와 배열을 저장하고 이것은 데이터를 저장하거나 메소드를 호출하는 데에 사용된다.
사용하지 않는 객체들은 가비지 컬렉터에 의해 삭제된다.
[Stack Area]
메소드 정보, 지역변수, 매개변수, 연산 중 발생하는 임시 데이터 저장한다.
메소드를 호출할 때마다 프레임(Frame)을 추가(push)하고 메소드가 종료되면 해당 프레임을 제거(pop)하 는 동작을 수행하며 선입후출(FILO, First In Last Out) 방식으로 한다.
[PC register]
현재 수행중인 JVM 명령 주소를 찾고
연산 결과값을 메모리에 전달하기 전 저장하는 기억장치이다.
[Native Method Stack]
자바 외 언어로 작성된 네이티브 코드를 위한 영역이고 네이티브 메소드의 매개변수, 지역변수 등을 바이트코드로 저장한다.
Excution Engine
Class Loader에 의해 로딩된 바이트코드를 기계어로 변환한다.
Garbage Collector
Heap 영역에 생성된 객체 중 참조되지 않은 객체를 삭제한다.