JDK/JRE/JVM? (feat. java 동작 원리)

JANG SEONG SU·2023년 7월 20일
0

Java

목록 보기
5/10
post-thumbnail

0.JDK/JRE/JVM 구조

JDK가 JRE, JVM 모두를 포함하고 있습니다. JRE는 다시 JVM을 포함하고 있다.
(JDK ⊃ JRE ⊃ JVM)


1.JDK

JDK(Java Development Kit)는 개발자들이 자바로 개발하는 데 사용되는 키트라 생각하면 된다.

그래서 JDK안에는 JRE와 Devlopment Tools(javac,java,javap,..)가 들어있다.

🔼JDK 디렉토리 구성 요소 🔼bin/ 에 들어있는 Development Tools
  • javac : 자바 컴파일러로 자바 소스를 바이트 코드로 컴파일
  • java : 자바 인터프리터. 컴파일러가 생성한 바이트 코드를 해석하고 실행
  • javadoc : 자바 소스로부터 HTML 형식의 API 도큐먼트 생성
  • jar : 자바 클래스 파일을 압축한 자바 아카이브 파일(.jar) 생성, 관리하는 압축 프로그램 (zip 같은거라 생각하면 된다)

자바의 컴파일러는 JRE가 아닌 JDK게 들어있다.


2.JRE

JRE(Java Runtime Environment)는 JDK를 다운로드할 때 기본적으로 포함되며 각 JRE에는 자바 클래스 라이브러리, 자바 클래스 로더, JVM 이 포함되어 있다.
클래스 로더, 클래스 라이브러리를 통해 작성한 자바 코드를 라이브러리와 결합한 후 JVM에 넘겨 실행시킨다. JRE는 그 자체로 특별한 기능을 한다기보다는 JVM이 원활하게 잘 작동할 수 있도록 환경을 맞춰주는 역할을 한다.

💡Class loader의 종류
1. Bootstrap class loader : JVM에 위치
2. Platform class loader : JRE에 위치
3. System class loader : JRE에 위치
참고 : Java ClassLoader 알아보기


3.JVM

과거의 모든 프로그램은 운영체제에 맞게 작성되었다. 같은 프로그램이지만 윈도우, 리눅스, 맥 등 사용하는 운영체제에 따라 다르게 작성되어야만 했다. 이렇듯 컴파일러가 운영체제마다 의존적이었던 문제를 해결하고자 JAVA가 등장하게 된다.

즉, 기계어(Binary Code)는 특정 OS나 CPU 구조에 맞춰진 컴파일러에 의해 다르게 컴파일이 된다는 특징이 있다.

JAVA 언어로 작성한 소스파일은 직접 운영체제로 가서 실행하는 것이 아닌, JVM(Java Virtual Machine)을 거쳐서 운영체제와 상호작용을 하게 된다.

이말은 JVM만 있으면 운영체제가 리눅스든, 맥이든 관계없이 운영체제로부터 독립적으로 프로그램을 제약없이 실행할 수 있다는 의미이다.

이것이 가능한 이유는 컴파일된 코드와 하드웨어/OS 사이 중간에서, 해당 하드웨어/OS 환경에 맞는 JVM이 Binary Code로 변환해주기 때문이다.

JVM 동작 과정

  1. Java Compiler가 JAVA로 작성된 소스 코드(.java 파일)를 .class 파일인 Byte Code로 컴파일한다. ⚠ Binary Code와 혼돈 주의!
    (단, 해당 코드는 직접 CPU에서 동작할 수 있는 코드가 아니다. 정확히 말하면 가상머신 JVM이 이해할 수 있는 코드이다)

  2. 이제 이 Byte Code를 기계어로 변환시키기 위해 가상 CPU가 필요한데, 이것이 JVM(Java Virtual Machine)의 역할이다.

  3. 그 전에 클래스 로더는 .Class 파일을 JVM의 메모리에 로드한다.

  4. 실행엔진(Execution Engine)은 JVM 메모리에 올라온 바이트 코드들을 명령어 단위로 하나씩 가져와서 실행하여, Binary Code로 변환한다.

    💡이때, 실행 엔진은 두 가지 방식으로 변경합니다.

    • 인터프리터 : 바이트 코드 명령어를 하나씩 읽어서 해석하고 실행합니다. 하나하나의 실행은 빠르나, 전체적인 실행 속도가 느리다는 단점을 가집니다.
    • JIT 컴파일러(Just-In-Time Compiler) : JAVA는 C언어와 달리 두번의 컴파일로 인한 속도의 문제가 발생하는데, 이를 보완하기 위해 JIT 컴파일러가 등장했다. 인터프리터의 단점을 보완하기 위해 도입된 방식으로 바이트 코드 전체를 컴파일하여 바이너리 코드로 변경하고 이후에는 해당 메서드를 더이상 인터프리팅 하지 않고, 바이너리 코드로 직접 실행하는 방식입니다. 하나씩 인터프리팅하여 실행하는 것이 아니라 바이트 코드 전체가 컴파일된 바이너리 코드를 실행하는 것이기 때문에 전체적인 실행속도는 인터프리팅 방식보다 빠릅니다.
  5. 실행엔진에 의해 변환된 Binary Code는 바로 CPU에서 실행되어 사용자에게 서비스를 제공해준다.

🔼전체적인 로직
profile
Software Developer Lv.0

1개의 댓글

comment-user-thumbnail
2023년 7월 20일

항상 좋은 글 감사합니다.

답글 달기