Java/The Java

[The Java] 클래스 로더와 JVM

메성 2021. 1. 3. 21:59
반응형

Java 프로그램의 실행 과정

  1. Java 프로그램을 실행하면 JVM은 OS로 부터 메모리를 할당받는다.
  2. 작성한 .java 파일은 컴파일러에 의해 .class(바이트 코드) 파일로 변환된다.
  3. 클래스 로더에 의해서 .class(바이트 코드가 포함된) 파일을 찾아 JVM에 올려놓는다.(런타임)
  4. 실행엔진에 의해 .class(바이트 코드가 포함된) 파일을 한줄 씩 실행하게 된다.

 

클래스 로더

  • 클래스 로더는 위 그림처럼 로딩 - 링크 - 초기화 순으로 진행된다.
  • 로딩
    • Bootstrap(최상위 부모) <- Extension(Platform) <- Application의 클래스 로더들이 부모 자식 관계를 맺고 있다.
      • 클래스 로더의 동작 : 클래스를 읽을 때, 최상위 부모에서부터 읽을 수 있는지 확인 후 못 읽으면 자식 클래스 로더로 내려온다. 만약 Application 클래스 로더도 못 읽게 되면 ClassNotFoundException이 발생하게 된다.
    • BootStrap : JVM이 실행될 때 실행되는 클래스 로더로서 $JAVA_HOME/lib/ext/*.jar에 있는 가장 기본이 되는 라이브러리들을 로드한다.
    • Extension : $JAVA_HOME/lib/ext/*.jar에 있는 클래스들을 로드한다. 
    • Application(System) : 사용자가 지정한 $CLASSPATH 내의 클래스들을 로드한다.
    • User-Defined(사용자 정의) : 사용자가 직접 코드 상에서 생성한 클래스들을 로드한다.
    • 전체적으로 클래스 로더가 .class 파일을 읽어 적절한 바이너리 데이터를 만들고 JVM의 메소드 영역에 저장한다.
      • 이 때 메소드 영역에 저장되는 데이터 : FQCN(패키지 이름, 풀 패키지 경로, 클래스 이름), 클래스, 인터페이스, Enum, 메소드와 변수
      • 이로 인해 java.lang.reflect 활용하여 로딩된 클래스들의 정보를 확인할 수 있다.
    • 로딩이 끝나면 해당 클래스 타입의 Class 객체를 생성하여 힙 영역에 저장한다.
  • 링크
    • Verify : 로드된 .class 파일의 형식이 유효한지 체크한다.
    • Preparation : 클래스 및 인터페이스의 static 필드를 생성하고 기본값으로 초기화한다.
    • Resolve : 심볼릭(명확하게 정의되지 않은)하게 참조한 메모리 부분을 인스턴스들의 실제 주소값으로 참조하게 한다.
  • 초기화
    • 링크 단계에서 기본값으로 초기화된 static 필드들에 대해 정의된 값으로 지정해준다.

 

 

JVM

  • 클래스 로더 시스템

    • .class에서 바이트 코드를 읽고 JVM의 메소드 영역에 저장한다.
    • 로딩 : 클래스를 읽어온다.
    • 링크 : 실제 주소값 참조
    • 초기화 : static 값들을 메모리에 할당한다.
  • 메모리

    • 메소드 영역에는 클래스 수준의 정보(클래스 이름, 부모 클래스 이름, 메소드, 변수)를 저장하고 공유한다. 전역변수도 포함되며 JVM에서 오직 한 영역만 존재하고 공유할 수 있어 다른 스레드에서도 접근이 가능하다.
    • 힙 영역에는 객체를 저장하는 것으로, JVM에서 오직 한 영역만 존재하고 공유할 수 있으며 이 영역 또한 다른 스레드에서 접근이 가능하다.
      • Class 객체의 인스턴스들도 저장된다.
    • 스택 영역에는 스레드마다 런타임 스택을 만들고, 그 안에서 메소드 호출을 스택 프레임이라 부르는 블럭으로 쌓는다. 또한,스레드마다 하나씩 갖고 있는다.
      • 소스에서 만든 메소드가 호출(스택 프레임)되면 스택 영역에 올라간다, 메소드 호출 범위가 종료되면 스택 영역에서 사라지게 된다.
      • 메소드의 매개변수, 지역변수, 리턴 값, 연산 시 결과 값들을 임시로 저장한다.
      • Ex. 오류가 발생했을 때 나오는 메소드 리스트들이 런타임 스택이다.
    • PC(Program Counter) 레지스터 스레드마다 하나씩 갖고 있으며, 현재 실행되고 있는 스택 프레임을 가리키는 포인터가 생성된다.
    • 네이티브 메소드 스택 자바로 작성되지 않고 C, C++로 작성된 메소드 스택이다. (기계어를 실행시키는 영역)
  • 네이티브 메소드 인터페이스(JNI)

    • Java가 아닌 C, C++로 작성된 메소드를 가진 인터페이스로서, Native 키워드를 사용하여 메소드를 호출한다.
    • 네이티브 메소드 인터페이스가 존재해야지만 네이비스 메소드 스택에 리스트가 존재한다.
  • 네이티브 메소드 라이브러리

    • 네이티브 메소드 인터페이스의 구현체이다.
  • 실행엔진

    • 인터프리터는 바이트 코드를 한줄씩 컴파일하여 네이티브 코드(컴퓨터가 읽을 수 있는 코드)로 변환하고 실행한다.
    • JIT 컴파일러는 인터프리터 방식의 단점을 보완하는 것이다.
      • 인터프리터는 한줄씩 실행하기 전에 반복되는 코드를 전부 찾아 JIT 컴파일러로 보내고, JIT 컴파일러는 받은 바이트 코드를 네이티브 코드로 변경해놓는다.
      • 그 후 인터프리터는 다시 실행하여 네이티브 코드면 그냥 사용하고, 그렇지 않은 것만 컴파일하는 것으로서, 좀 더 빠르게 되는 것이다.
  • GC

    • 힙 영역에 있는 New/Young Generation과 Old Genaration 영역에 있는 객체들을 정리한다.
    • New/Young Generation은 Minor GC가 발생하고 Old Generation은 Major GC가 발생한다.

https://it-mesung.tistory.com/56

 

[Java 기초] JVM 구조

Java Virtual Machine JVM이란 Java 애플리케이션을 클래스 로더를 통해 읽어 들여 Java API와 함께 실행하는 것을 말한다. JVM은 Java와 OS 사이에서 중개자 역할을 하며 Java가 OS에 구애받지 않고 재사용을 가..

it-mesung.tistory.com

 

GC에 대해서 더 살펴보자

https://it-mesung.tistory.com/58

 

[Java 기초] GC에 대해서

Garbage Collection 가비지 컬렉션과 관계된 객체 참조 방식들 객체 참조 방식 Java 프로그램에서 하나의 객체는 다른 객체를 참조하고 다른 객체는 또 다른 객체를 참조하는 참조 사슬이 형성되는데, 이 참조 사..

it-mesung.tistory.com

 

반응형