본문 바로가기
Programming Language/Java

[Java/개념] JVM(Java Virtual Machine) 동작 과정

by wo__ongii 2024. 10. 7.
728x90
반응형

[JVM(Java Virtual Machine) 동작 과정]

JVM은 자바 프로그램을 효율적으로 실행하기 위해 다음과 같은 과정을 수행한다.

 

  • 컴파일 수행: 자바 소스 파일(.java)을 자바 컴파일러가 바이트 코드(.class 파일)로 변환
  • 클래스 로딩: Class Loader가 바이트 코드를 메모리에 로드하고, 메모리 영역에 클래스 정보를 할당
  • 메모리 할당: JVM의 Heap과 Stack에 필요한 메모리를 할당하여 객체와 지역 변수를 저장
  • 바이트 코드 해석 및 실행: Execution Engine이 바이트 코드를 해석하여 기계어로 변환하고, 프로그램을 실행, 반복적인 코드는 JIT 컴파일러가 최적화하여 실행
  • 가비지 컬렉션: Garbage Collector가 사용되지 않는 객체를 메모리에서 제거하여 메모리 누수를 방지
  • 예외 처리: 프로그램 실행 중 발생하는 **예외(Exception)**를 처리하며, 비정상적인 종료를 방지하고 오류를 관리
  • 프로그램 종료: 모든 작업이 완료되면 JVM이 프로그램을 종료하고, 할당된 메모리를 해제

JVM 전체 동작 과정

 

https://woongii.tistory.com/99

 

[Java/개념] 자바 가상 머신(Java Virtual Machine)

자바 가상 머신(JVM)은 자바 프로그램을 실행하는 가상의 운영체제입니다. 자바 프로그램은 중간 단계의 바이트코드를 사용하므로, 이를 실행할 수 있는 JVM이 필요합니다. JVM은 자바 프로그램이

woongii.tistory.com

 

 

1. 컴파일(compile)

 

자바 프로그램을 실행시키는 시점에 자바 소스 코드(.java)를 컴파일러(javac)를 통해 바이트 코드(.class)로 변환을 수행한다. 이 변환된 바이트코드는 플랫폼에 대해 독립적이며 JVM이 실행할 수 있는 언어로 변환한다. 해당 과정은 Java Source File(java) → (Java Complier) → Java Byte Code(class)에서 수행한다.

 

2. 클래스 로딩(class loading)

 

JVM에 컴파일된 바이트 코드를 읽고 메모리에 로드를 수행합니다. 해당 메모리가 로드되는 시점은 ‘파일을 실행(Runtime)’ 할 때이며 ‘Runtime Data Areas’로 로딩시킨다. 해당 과정은 Java Byte Code(class) → Class Loader에서 수행한다.

 

3. 메모리 할당(Memory Allocation) 

 

메모리에 로딩되어 온 데이터나 코드들에 대해 ‘Runtime Data Areas’에 크기에 맞게 메모리를 할당 및 부여하는 것을 수행힌다. 메모리 할당은 주로 힙 영영에 객체나 배열이 생성될 때 객체의 크기에 맞게 힙 영역에 메모리를 할당한다. 해당 과정은 Class Loader → Runtime Data Areas에서 수행한다.

 

4.  바이트 코드 해석 및 실행(Byte Code Interpretation and Runtime) 

 

JVM의 클래스 파일의 ‘바이트 코드를 해석’하여 명령어를 수행하는 역할을 수행한다. 해당 역할을 Execution Engine의 Interpreter와 JIT가 수행을 하며 네이티브 코드에 대한 해석은 Native Method Interface, Native Method Libaray에서 수행한다. 이때 JVM은 스택 기반의 가상머신으로 동작하여 스택 프레임을 사용하여 메서드 호출과 반환을 관리한다. JVM 내에서 Runtime Data Area와 Execution Engine(JIT, Interpreter)에서 수행한다.

 

 

1) 인터프리터(Interpreter)의 바이트 코드 수행 및 실행 과정

  • 이전에 생성하고 할당된 메모리를 기반으로 바이트 코드를 읽어온다.
  • 인터프리터를 통해 바이트 코드를 한 줄씩 읽고 해석한다.
  • 바이트 코드를 해석하는 동안 인터프리터는 필요한 메모리 및 리소스를 할당하고 해당 바이트 코드에 따라 실행한다.
  • 바이트 코드가 실행되는 동안 인터프리터는 필요한 경우에 따라 라이브러리 및 다른 클래스를 로드하고 사용한다.
  • 인터프리터는 바이트 코드를 순차적으로 해석하면서 프로그램을 실행한다.

2) JIT(Just-In-Time)의 바이트 코드 수행 및 실행 과정

    • 이전에 생성하고 할당된 메모리를 기반으로 바이트 코드를 읽어온다.
    • JIT 컴파일러는 실행 중인 프로그램을 모니터링하면서 빈번하게 실행되는 코드 블록을 식별한다.
    •  해당 코드 블록은 인터프리터에 의해 실행될 때마다 JIT 컴파일러에 의해 기계어로 변환된다.
    • JIT 컴파일러는 변환된 기계어 코드를 캐시에 저장한다.
    • 이후 동일한 코드 블록이 다시 호출되면, 캐시에 저장된 기계어 코드를 실행하여 인터프리터에 비해 훨씬 빠른 실행 속도를 제공한다.

3)Native Method Interface의 바이트 코드 수행 과정

 

Java 프로그램이 C 또는 C++과 같은 네이티브 코드를 호출하고 상호 작용할 수 있게 해주는 기능을 제공한다. 해당 부분은 JVM이 바이트 코드를 해석하고 실행하는 동안 네이티브 메서드를 호출하고 해당 코드가 네이티브 코드로 실행될 수 있도록 한다.

 

4)Native Method Libaray의 바이트 코드 수행

 

C 또는 C++과 같은 특정 프로그래밍 언어로 구현된 네이티브 메서드의 컬렉션입니다. 추가 기능이나 시스템 수준의 리소스에 액세스 할 수 있는 기능을 제공합니다. 해당 부분은 JVM이 바이트 코드를 해석하는 동안 호출되고 실행된.

 

5.  가비지 컬렉션 (GC, Garbage Collection)

 

VM에서 더 이상 사용되지 않은 객체를 자동으로 감시하고 메모리에서 자동으로 해제하는 역할을 수행합니다. 이를 통해 메모리 관리를 최적화할 수 있다. JVM 내에서 Execution Engine(Garbage Collection)에서 수행한다.

  • Marking (표시) : 가비지 컬렉터는 모든 객체를 스캔하고 참조되는 객체들을 표시합니다. 이 과정에서 도달 가능한 객체들은 표시됩니다.
    Sweeping (정리) : 가비지 컬렉터는 표시되지 않은 객체들을 메모리에서 제거합니다. 이러한 객체들은 도달할 수 없는 객체로 간주되며 가비지로 처리됩니다.
    Compacting (압축) : 가비지 컬렉터는 메모리에서 제거된 객체들로 인해 생긴 빈 공간을 모아서 압축합니다. 이렇게 함으로써 메모리의 단편화를 최소화하고, 연속된 메모리 공간을 확보합니다.

6.  예외처리(Exception Handling) 

 

예외처리는 프로그램 실행 도중 발생하는 예기치 않은 상황으로, 예외가 발생하면 JVM은 해당 예외를 적절히 처리하고 예외 상황에 대한 적절한 조치를 취한다. JVM은 예외 처리를 위해 예외 핸들러를 사용하며, 예외가 발생했을 때 해당 예외를 처리할 수 있는 예외 핸들러를 찾아 처리한다.

 

  • 예외 발생 : 프로그램이 실행 중에 예외가 발생합니다. 이는 예상치 못한 상황 또는 오류가 발생한 것을 의미한다.
  • 예외 객체 생성 : 예외가 발생하면 JVM은 해당 예외를 나타내는 예외 객체를 생성합니다. 이 객체는 예외의 유형, 메시지 및 예외가 발생한 위치 정보를 포함한다.
  • 예외 처리 : JVM은 예외를 적절히 처리하기 위해 예외 처리기(Exception Handler)를 찾습니다. 예외 처리기는 예외를 처리하는 코드 블록으로, 예외를 처리하는 방법을 정의한다.
  • 예외 전파 : 예외 처리기가 발견되지 않거나 처리하지 못한 경우, 예외는 현재 실행 중인 메서드에서 호출한 메서드로 전파됩니다. 이 과정은 메소드 호출 스택을 따라 위로 올라간다.
  • 예외 처리기 찾기 : 예외는 예외를 전파한 메서드의 호출자에게 전달됩니다. JVM은 호출자 메서드에서 예외 처리기를 찾습니다. 이 과정은 호출자 메서드의 호출자로 계속해서 진행된다.
  • 예외 처리 : 예외 처리기가 발견되면 예외 처리기의 코드 블록이 실행됩니다. 예외 처리기는 예외를 처리하거나 예외를 다시 던지는 등의 작업을 수행할 수 있다.
  • 예외 체인 : 예외 처리기가 예외를 다시 던지는 경우, 예외는 다시 호출자로 전파되며, 이 과정은 호출자 메소드의 호출자로 계속해서 진행된다. 이렇게 예외가 여러 단계로 전파되는 구조를 예외 체인(Exception Chaining)이라고 한다.

 

7. 프로그램 종료(End of Program)

프로그램 실행이 완료되거나 명시적으로 종료되면 JVM은 사용한 메모리를 반환하고 자원을 정리한다.

  • 정리 작업 : 프로그램이 종료되기 전에 필요한 정리 작업을 수행한다. 이는 열려 있는 파일을 닫고, 할당된 리소스를 해제하는 등의 작업을 포함할 수 있다.
  • 종료 코드 반환 : 프로그램이 완전히 종료되었을 때, 종료 코드를 반환한다. 종료 코드는 프로그램이 성공적으로 종료되었는지 또는 오류로 종료되었는지를 나타내는 값이다.
  • 자원 해제 : 프로그램이 사용한 모든 자원을 해제한다. 이는 할당된 메모리의 해제, 열려 있는 연결의 닫힘 등을 포함할 수 있다.

 

 

 

 

[출처: https://adjh54.tistory.com/279, https://interviewnoodle.com/jvm-architecture-71fd37e7826e
이미지 출처: https://jungeu1509.github.io/interview/JAVA_Compile/, https://ee-22-joo.tistory.com/38, https://velog.io/@dyunge_100/JAVA-JVM%EC%9D%98-%EB%A9%94%EB%AA%A8%EB%A6%AC-%EA%B5%AC%EC%A1%B0-%EB%B0%8F-%EB%8F%99%EC%9E%91-%EC%9B%90%EB%A6%AC]

728x90
반응형