본문 바로가기
개발자 일지/Java

JAVA JVM(Java Virtual Machine)의 개념, 구조, 작동과정

by 네빌링 2021. 2. 27.
반응형

-컴파일된 파일을 실행하는 가상머신인 JVM(Java Virtual Machine)에 대해 알아본다.


JVM이란?

컴파일러가 컴파일한 파일을 실행하는 가상 머신이다. '가상'의 머신이기 때문에 하드웨어적인 요소가 아니라 JDK에 포함된 일종의 프로그램이다.
개발자는 인간이 이해 가능한 영어로 자바 문법에 맞게 코드를 java파일로 작성한다.  java파일은 컴파일러를 통해 자바 바이트코드로 작성된 class파일로 변환된다.
자바 바이트코드로 변환된 파일은 가상머신인 JVM이 해석할 수 있게 된다.
그렇기 때문에 JVM만 설치되어 있다면 어떤 운영체제(OS)에서도 실행가능하다.

기존의 C++같은 경우에는 컴파일한 파일이 OS에 종속된다. 예를 들어 리눅스기반 OS에서 개발하고 컴파일을 했다면 윈도우에서는 바로 실행시킬 수 없다. 이런 경우 크로스 컴파일 과정을 거쳐야 한다.

JDK, JRE, JVM


항상 용어가 헷깔린다. 다시 정리한다.

  • JDK : Java Development Kit. 자바 기반 소프트웨어 개발 도구이며 JRE, 컴파일러를 가지고 있다.
  • JRE : Java Runtime Enviroment. 자바코드를 실행하기 위한 환경이며 JVM을 가지고 있다.
  • JVM : Java Virtual Machine. 바이트코드를 OS, 하드웨어에 맞게 처리해주는 가상 머신이다.

자바의 작동 과정


자바의 작동 과정을 다시 간략하게 정리해본다.

  1. Java언어로 프로그램 작성
  2. JDK에 포함된 컴파일러에 의해 Java파일이 Bytecode기반의 class파일로 변환
  3. 변환된 파일은 JRE에 포함된 JVM의 클래스로더에 의해 메모리에 로드
  4. 링킹(Linking)을 통해 에러 등을 확인
  5. 초기화

JVM구조


JVM의 구조로 클래스로더, 데이터영역, 실행엔진으로 크게 구분된다.




1.클래스 로더 서브시스템(Class Loader Subsystem)

JVM에 존재하며 클래스를 메모리(RAM)에 로드해서 실행할 수 있게 해주는 역할을 한다.
이를 자바의 동적 클래스 로딩이라고 한다.

클래스 파일은 런타임될 때 그림과 같이 loads → links → initialize 과정을 거친다.

  1. 클래스로더(Loading-적재)
    • 컴파일된 클래스를 메모리에 적재한다. 내부에는 3가지 종류의 클래스로더가 존재한다.
    • 1)부트스트랩 클래스 로더(Bootstrap class loader)
      • 클래스로더 자체를 로드하는 역할을 한다. 또한 rt.jar, 코어자바 API 등 일반적인 JDK 클래스를 로드한다.
      • C,C++같은 Native Language로 작성되어 있다.
    • 2)익스텐션 클래스 로더(Extension class loader)
      • 상위로더인 부트스트랩 로더에 클래스 로딩을 부탁하는 역할을 한다.
      • 부탁할 필요가 없으면 extensions directories인 ext/*.jar에 있는 클래스들을 실행한다.
    • 3)시스템/어플리케이션 클래스 로더(System/Application class loader)
      • 시스템의 클래스패스(classpath)를 따라서 클래스 파일 자체를 JVM으로 로드한다. 우리가 실제로 코딩한 파일들이 메모리에 올라갈 수 있도록 도와주는 역할을 한다.
  2. 연결(Linking)
    • 로드된 클래스나 인터페이스를 확인하고 준비하는 과정을 한다.
    • 클래스, 인터페이스는 링크되기 전에 반드시 적재(로드)되어야 한다.
    • 링크는 3단계로 나뉜다.
      • 1)Verification(확인)
        • class파일 정확성을 확인해야 하는데 Java로 적합하게 작성되었는지, 유효한 컴파일러로 생성되었는지 확인한다.
        • 가장 복잡하고 시간이 오래 걸리는 작업이다.
        • 이때 오류가 발생하면 런타임 에러(Runtime Error)가 발생한다.
      • 2)Preparation(준비)
        • JVM에 의한 데이터 구조나 Static 저장공간을 위해 메모리를 할당하는 과정이다.
      • 3)Resolution(실행)
        • Symbolic reference가 Direct reference로 바꿔준다.
  3. 초기화(Initialization)
    • Static 변수 값을 할당한다.(static 선언 있는 경우)
    • SuperClass 초기화를 진행하고 이후 해당 Class의 초기화를 진행한다.

2.Runtime Data Area

JVM이 OS에서 실행될 때 메모리에 지정된 영역들이며 아래는 각각의 구분이다.

  1. Method area
    • JVM당 1개만 존재하는 공유자원이다.
    • 모든 JVM의 스레드는 이 공간을 공유한다.
    • Constant pool(숫자 상수, 필드, 참조 등), Field data(이름, 타입, 접근제어자, 속성), Method data(이름, 리턴타입, 파라미터 타입, 접근제어자, 속성 등)의 정보를 저장한다.
  2. Heap area
    • Heap 영역도 JVM당 1개만 존재하는 공유자원이다.
    • 모든 객체들과 인스턴스 변수, 배열 등이 저장되어 있다.
    • Method area, Heap area는 다중스레드에 의해 공유되어 thread safety하지 않다.
    • GC(Garbage Collector)의 좋은 타겟이다.
  3. Stack area
    • 스레드당 하나씩 존재하며 공유자원이 아니다.
  4. PC Register
    • 프로그램 카운터로 스레드 당 하나씩 존재한다.
  5. Native Method Stack
    • 자바 스레드와 네이티브 코드(C,C++)로 작성된 코드 사이를 매핑하는 역할을 한다.

3. Execution Engine

컴파일러가 변환한 바이트코드가 실제로 실행되는 공간이다. Runtime Data Area를 위해 바이트코드를 한줄 한줄 읽는다. 3가지로 구성된다.

  1. 인터프리터
    • 바이트코드를 한줄한줄 읽고 실행한다.
  2. JIT 컴파일러(Just In Time Compiler)
    • 자바는 바이트코드로 변환한 후에, 다시 기계어로 변환해야하기 때문에 C보다 느리다.
    • 이를 극복하기 위해 기계어로 변경된 것들을 저장해두었다가 다음 사용시 그대로 사용한다.
    • 이떄 사용된 기계어는 캐시에 저장된다.
  3. 가비지컬렉터(GC : Garbage Collector)
    • 객체가 더 참조되지 않으면 GC가 삭제를 하고 메모리를 더 이상 사용되지 않는 영역으로 만든다.
    • System.gc()로 직접 호출이 가능하다.

4.JNI(Java Native Interface)

잘 이해를 못했던 부분이라 다시 찾아보았다. 자바의 특성과 연관된 부분이라고 볼 수 있다. 자바는 운영체제에 종속되지 않고 JVM에 의해 여러 운영체제에서 실행될 수 있다는 장점을 갖고 있다. 그러나 이런 유연한 실행환경 때문에 JVM이 운영체제의 기능을 다 담을 수 없다. 따라서 구현하고싶은 몇몇 기능은 Java 언어로 해결할 수 없다.

그래서 운영체제 고유기능(Native)을 운영체제가 구현된 언어인 C, C++로 운영체제의 고유 기능을 만든다. JVM은 이렇게 만들어진 고유기능과 Java의 메서드를 연결하여 자바에서도 사용할 수 있게 해준다.

JNI는 JVM위에서 실행되어 Java와 고유기능을 연결해주는 프레임워크라고 볼 수 있다.


출처 : mommoo.tistory.com/71, nesoy.github.io/articles/2020-11/ClassLoader, ko.wikipedia.org/wiki/%EC%9E%90%EB%B0%94_%EB%84%A4%EC%9D%B4%ED%8B%B0%EB%B8%8C_%EC%9D%B8%ED%84%B0%ED%8E%98%EC%9D%B4%EC%8A%A4

반응형