JAVA

JDK JRM JVM 및 자바 실행 과정

흰곰돌이 2024. 2. 16. 18:55

Java는 쉽게 말해서 클래스 단위로 프로그래밍을 하는 객체지향 프로그래밍이다.

그렇다면 개발과 실행에 있어서 필요한 것은 무엇일까?

 

JDK(자바 개발 시 필요한 라이브러리와 개발 도구가 포함되어 있음, JRE 역시 포함)

JRE(자바 프로그램을 실행(동작)시킬 때 필요한 라이브러리 API를 배포하는 패키지다)

JVM(자바 가상 머신, 자바를 돌리는 프로그램, 작성한 자바 프로그램이 OS에서 실행 가능하도록 번역 실행 환경을 제공하는 자바 프로그램의 구동 엔진)

 

자바 11 이상 버전에서는 전통적인 의미에서의 별도 JRE 폴더가 JDK 설치와 함께 제공되지 않는다. 이는 JDK가 JRE의 모든 기능을 포함하고 있기 때문이다. 따라서, JDK를 설치하면 JRE가 설치되어 있는 것으로 간주할 수 있지만, 이전 버전의 자바처럼 독립된 JRE 폴더는 존재하지 않는다.

자바 11 이상의 JDK는 자바 애플리케이션을 실행하는 데 필요한 런타임 환경을 내장하고 있다. 이는 java 실행 파일을 포함하여, 자바 애플리케이션을 실행하는 데 필요한 모든 라이브러리와 JVM을 포함한다. 따라서, JDK의 bin 디렉토리 안에 있는 java.exe를 사용하여 자바 애플리케이션을 실행할 수 있으며, 이는 JRE의 기능을 수행한다.

즉, JRE는 기본적으로 JDK에 포함되어 있기 때문에 JDK를 설치하면 함께 설치된다. 단, 자바 11 버전 미만에서는 별도의 JRE 폴더가 함께 설치되는 구조이며, 11 버전 이상부터는 JRE 폴더가 따로 제공되지 않고 JDK 폴더 내에 기능이 모두 내장되어 있다. 그리고 11 버전 미만에서는 JRE만 따로 설치할 수 있지만, 11 버전 이상부터는 따로 제공되지 않는다.

 

자바의 실행 과정은 다음과 같다.

  1. 소스 코드 작성: 개발자는 .java 확장자를 가진 파일에 자바 언어로 소스 코드를 작성한다.
  2. 컴파일 과정 (javac.exe): 자바 컴파일러인 javac.exe를 사용하여 소스 코드 파일을 컴파일한다. 이 과정에서 소스 코드는 중간 언어인 바이트 코드로 변환되며, 결과물로 .class 파일이 생성된다. 이 바이트 코드는 플랫폼에 독립적이어서 다양한 운영 체제에서 JVM(Java Virtual Machine)을 통해 실행될 수 있다.
  3. 실행 과정 (java.exe): 자바 인터프리터인 java.exe를 사용하여 컴파일된 .class 파일을 실행한다. 이 때, JVM이 호출되고 다음과 같은 과정을 거친다. (java.exe를 인터프리터라고 부르는 것은 이 실행 파일이 JVM을 시작하고, JVM 내의 인터프리터와 JIT 컴파일러를 통해 자바 프로그램을 실행하는 전체 과정을 간략하게 지칭하는 방식이다. 기술적으로 정확한 표현을 위해서는 java.exe가 JVM을 구동하는 역할을 하며, 실제 인터프리팅은 JVM 내부에서 이루어진다고 설명하는 것이 적절하다)
    • Class Loader: JVM의 Class Loader가 .class 파일을 로딩하여 JVM 내부로 가져온다.
    • 링킹: 로딩된 클래스 파일들이 서로 참조하는 부분들을 연결한다.
    • 초기화: 클래스 변수들의 초기화 등 초기화 작업을 수행한다.
  4. Runtime Data Area 배치: Class Loader에 의해 로드된 클래스는 Runtime Data Area에 배치된다. 이 영역에는 클래스와 인스턴스 변수, 메소드 데이터 등이 저장된다.
  5. 실행 엔진 처리: JVM의 실행 엔진이 Runtime Data Area에 있는 바이트 코드를 한 줄씩 읽어서 기계어로 변환한다. 이 과정에서 필요에 따라 JIT(Just-In-Time) 컴파일러를 사용하여 바이트 코드의 일부를 더 효율적으로 실행할 수 있는 기계어로 변환한다. (인터프리터 방식으로 읽되, 중복되는 부분은 JIT 컴파일러가 컴파일 방식으로 읽는다)
  6. 운영체제에서 실행: 변환된 기계어는 최종적으로 운영체제에서 실행되며, 실행 결과는 JVM을 통해 사용자에게 반환된다.

 

5, 6 을 좀 더 들여다 보면,

기계어로 변환된 후의 실행은 운영 체제(OS)가 담당한다. 자바 가상 머신(JVM)은 자바 바이트코드를 기계어로 변환하는 역할을 하지만, 실제로 변환된 기계어 코드를 실행하는 것은 운영 체제의 책임이다. 이 과정을 상세하게 설명하면 다음과 같다.

  1. 바이트코드를 기계어로 변환: 자바 프로그램이 실행될 때, JVM은 자바 바이트코드를 기계어로 변환한다. 이 변환 과정은 주로 두 가지 방식으로 이루어진다.
    • 인터프리터: JVM의 인터프리터가 바이트코드를 한 줄씩 읽어서 직접 기계어로 변환하고 실행한다. 이 방식은 실행 속도가 느릴 수 있다.
    • JIT(Just-In-Time) 컴파일러: 프로그램 실행 중에 바이트코드의 '핫 스팟'(자주 실행되는 코드 부분)을 식별하고, 이를 기계어로 미리 컴파일한다. 이렇게 컴파일된 코드는 실행 시 빠르게 처리된다.
  2. 기계어 코드의 실행: 기계어로 변환된 코드는 CPU가 직접 실행할 수 있는 형태다. 이 기계어 코드의 실행은 운영 체제의 관리 하에 이루어진다. 운영 체제는 프로세스 관리, 메모리 관리, I/O 관리 등을 통해 변환된 기계어 코드가 효율적으로 실행될 수 있도록 한다.

즉, JVM은 자바 프로그램을 실행하기 위해 필요한 바이트코드를 기계어로 변환하는 중간자 역할을 하며, 실제로 CPU에서 실행되는 기계어 코드는 운영 체제의 관리 아래에서 처리된다. 이 과정에서 운영 체제는 자원 할당, 스케줄링, 실행 제어 등의 역할을 담당하여 최종적으로 변환된 기계어 코드가 하드웨어에서 실행될 수 있도록 한다.

 

 

위의 일련의 실행 과정을 통해 자바 코드는 다양한 환경에서 실행될 수 있는 이식성과 함께, JVM과 JIT 컴파일러 등의 최적화를 통해 높은 성능을 제공한다.

JAVA는 한번만 작성되면 각 OS에 맞는 JVM만 잘 설치해주면 구동되기에 효율성과 생산성이 높아진다는 큰 장점을 가지게 된다. 즉 OS에 독립적이다(어떤 운영체제에서든 잘 녹아들 수 있다).

자바 프로그램은 일반 프로그램보다 자바 가상 머신이라는 한 단계를 더 거쳐야 하므로, 결국은 상대적으로 실행 속도가 느리다는 단점을 가지고 내포하고 있다. 그래도 JIT 컴파일러를 통해 필요한 부분만을 기계어로 바꾸어 줌으로써 성능 향상을 가져오도록 했지만 그럼에도 C언어의 실행 속도를 따라잡지는 못했다.

출처 : https://inpa.tistory.com/entry/JAVA-%E2%98%95-JDK-JRE-JVM-%EA%B0%9C%EB%85%90-%EA%B5%AC%EC%84%B1-%EC%9B%90%EB%A6%AC-%F0%9F%92%AF-%EC%99%84%EB%B2%BD-%EC%B4%9D%EC%A0%95%EB%A6%AC

 

 

 

참고 출처 : https://inpa.tistory.com/entry/JAVA-%E2%98%95-JDK-JRE-JVM-%EA%B0%9C%EB%85%90-%EA%B5%AC%EC%84%B1-%EC%9B%90%EB%A6%AC-%F0%9F%92%AF-%EC%99%84%EB%B2%BD-%EC%B4%9D%EC%A0%95%EB%A6%AC