개발/Spring

JVM이란?

728x90

JVM의 정의

  • 자바 가상 머신(영어: Java Virtual Machine, JVM)은 자바 바이트코드를 실행할 수 있는 주체이다.
    • (가상 머신 : 물리적 컴퓨터와 동일한 기능을 제공하는 소프트웨어적으로 구현한 컴퓨터 )
  • 특징
    • Java와 OS사이에서 중개자 역할을 하며, OS에 구애받지 않고 재사용 가능하게 해준다.
    • 그리고 가장 중요한 GC(사용하고 남아 있는 전혀 필요없는 객체들을 정리)를 수행한다.

JVM의 구조

  • Runtime Data Area
    • JVM이 OS위에서 실행되면서 할당받은 메모리 영역.
    • 구성요소
      • Stack : 스택 프레임이라는 구조체를 저장하는 스택. 스레드들이 독립적으로 갖고 있는 공간.
        • Stack Frame : JVM내에서 {} 중괄호가 지삭될 때 마다 하나의 스택 프레임이 생성되고, 중괄호가 닫히면 스택 프레임이 제거된다. 현재 실행중인 메서드가 속한 클래스의 런타임 상수 풀에 대한 참조를 갖는다.
      • Heap : 인스턴스 정보가 담기는 공간. 스레드들이 공유함.
        • 구성 요소 
          • Young Generation
            • Eden : 객체들이 최초로 생성되는 공간
            • Survivor 0 : Eden영역에서 마이너 GC가 발생하고 이곳으로 이동한다.
            • Survivor 1 : 0에서 가득차게 되면, 이곳으로 이동하게 된다. 그리고 0은 아무 데이터도 없는 상태가 된다.  이 과정을 반복하다가 계속해서 살아남아 있는 객체는 Old 영역으로 이동하게 된다. 0,1중 하나는 반드시 비어있는 상태가 된다.
          • Old Generation : Young영역에서 살아남은 객체들이 저장되는 곳.
          • Permanent Generation : 생성된 객체들의 주소값이 저장된 공간. 
          • GC : 지역변수, 정적변수, 실행중인 스레드, JNI에서 참조되지 않는 객체들은 Unreachable하여 GC의 대상이 된다.
        • 대부분 객체는 금방 소멸된고 Young에서 Old로의 참조가 적어서 위와같이 메모리 공간이 나뉘었다.
      • Static : 클래스 정보가 담기는 공간. 스레드들이 공유함. 
        • 구성요소
          • 런타임 상수풀 (클래스와 인터페이스 상수, 메서드와 필드에 대한 모든 메모리 주소를 담고 있는 테이블)
            • 어떤 메서드나 멤버변수를 참조할 때 JVM은 런타임 상수 풀을 통해 해당 메서드나 멤버변수 실제 메모리 주소를 참조한다.
          • 필드 정보
            • 멤버변수의 이름, 타입, 접근제어자
          • 메소드 정보
            • 메소드의 이름, 리턴타입, 매개변수, 접근제어자
          • 타입정보
            • 클래스인지 인터페이스인지, 리턴타입, 부모 클래스 등
        • 메모리 공간에 올릴 때 초기화 되는 대상을 저장하기 위한 메모리 공간.
      • PC Register : 스레드가 어떤 부분을 어떤 명령으로 실행할 지에 대한 기록하는 부분. 현재 수행중인 주소와 명령을 저장함. 스레드들이 독립적으로 갖고 있는 공간.
      • Native Method Stack : 스레드들이 독립적으로 갖고 있는 공간. Java Native Interface가 저장되는 공간
  • Class Loader
    • 컴파일된 자바 바이트코드를 Runtime Data Area 영역으로 로드한다.
    • 런타임에 클래스를 처음으로 참조할 때 클래스를 로드함.
    • 종류
      • 부트스트랩 클래스로더 : 최상위 클래스로더, Object 클래스를 비롯하여 Java API들을 로드함
      • 익스텐션 클래스로더 : 확장 클래스들을 로드함
      • 시스템 클래스로더 : 어플리케이션의 클래스들을 로드함
      • 사용자 정의 클래스로더 : 사용자가 직접 코드상에서 생성하여 사용함
    • 특징
      • 계층구조 : 클래스로더끼리 부모-자식 관계를 이뤄 계층 구조로 생성된다.
      • 위임모델 : 클래스로딩 요청은 부모 로더들로 거슬러 올라가서 부트스트랩 로더에 다다른 후 클래스를 못찾으면 그 밑으로 로딩 요청을 수행.
      • 가시성제한 : 하위 클래스를 상위 로더를 찾을 수 있지만, 그 반대는 안됨.
      • 언로드 불가 : 클래스를 로드할 수 있지만 거꾸로는 불가능함.
    • 클래스 로드 과정(Loading,Linking,Initalization)
      • Loading : 클래스파일을 가져와서 JVM의 Runtime Data Area의 스태틱 영역에 탑재한다.
      • Vertification : 클래스 로드 전 JVM 명세대로 구성되어 있는지 검사한다.
      • Preparation : 클래스가 필요로 하는 메모리를 할당하고 디폴트 값으로 초기화 됨. (클래스 멤버변수, 메서드, 인터페이스 등)
      • Resolution : 클래스 상수 풀 내의 모든 심볼릭 레퍼런스를 다이렉트 레퍼런스로 변경 (참조하는 대상의 이름만 지칭하는 것 대신에 실제로 존재하는 물리적인 주소로 대체함)
      • Initialzation : 클래스 로딩의 마지막 단계, 모든 클래스 변수들을 초기화함.
      • *Linking : 메모리를 할당하고 클래스 상수 풀 내의 모든 레퍼런스를 할당된 메모리로 연결하는 과정(Vertification, Prepareation, Resolution)
  • Execution Engine
    • JVM내의 런타임 데이터 영역에서 배치된 바이트 코드를 실행하는 역할
    • 1바이트 코드의 Operation code와 추가 피연산자로 이뤄짐. 
      • Interpreter : JVM에서 기본적으로 실행되는 방식. 바이트코드 명령어를 하나씩 읽어서 해석하고 실행함. 하나하나의 해석은 빠르지만 전체적인 실행속도는 느림. 
      • JIT (Just-In-Time)
        • 인터프리터 방식의 단점을 보완하기 위해 도입됨. 인터프리터 방식으로 실행하다가, 적절한 시점에 바이트 코드 전체를 컴파일 하여 네이티브로 변경하고, 더 이상 인터프리팅 않고 네이티브 코드로 직접 실행하는 방식.
        • 내부적으로 프로파일링을 통해 가장 컴파일리 필요한 핫스팟을 찾아 캐싱하고 자주 사용되지 않으면 다시 인터프리터 모드로 동작함.

 

 

JVM의 실행 순서

 

  • JVM은 OS로부터 어플리케이션에 필요로 하는 메모리를 할당받는다.
  • 자바 소스(.java)인 파일을 자바 컴파일러를 통해 자바 바이트코드로 컴파일(컴퓨터가 이해할 수 있는 언어로 번역해주는 과정) 한다.
  • 컴파일된 바이트코드를 JVM의 클래스로더에게 전달한다.
  • 클래스로더는 동적로딩을 통해 필요한 클래스들을 로딩 및 링크하여 런타임 데이터 영역, JVM의 메모리에 올린다.
  • Loading 로드 : 클래스 파일을 가져와서 JVM의 메모리에 로드한다. (스태틱 영역에 탑재)
    • 로드된 클래스를 비롯한 그의 부모 클래스의 정보.
    • Class 파일이 Class, Interface, Enum와 관련 여부.
    • 변수나 메소드 정보
  • Vertification 검증 : 클래스 로드 전 과정중에 가장 복잡하고, 시간이 오래걸린다. JVM 명세에 명시된대로 구성되어 있는지 검사한다.
  • Preparation 준비 : 클래스가 필요로 하는 메모리를 할당한다. 여기서 필요한 메모리는 멤버변수, 메서드, 인터페이스들을 나타내는 데이터의 구조 등등을 말함.
  • Resoultion 분석 : 클래스 상수 풀 내 모든 심볼릭 레퍼런스를 다이렉트 레퍼런스로 변경
  • Initialzation 초기화 : 클래스 변수들을 초기화 한다.
  • 로딩된 클래스 파일(바이트코드)들은 Execution Engine을 통해 명령어 단위로 해석된다.
  • 이 과정에서 Thread Synchonzation과 GC관리 작업을 수행한다.

JVM에게 코드가 전달되기 까지의 과정
클래스로더 실행과정

'개발 > Spring' 카테고리의 다른 글

가비지 컬렉터  (0) 2021.03.01
java.lang 패키지  (0) 2021.02.28
Hot Spot JVM이란?  (0) 2021.02.27
JIT란?  (0) 2021.02.27
자바(JDK)의 버전별 차이 JDK 1.4  (0) 2021.02.27