JVM의 구조와 Java의 실행방식을 설명해주세요

한상우·2022년 10월 12일
0

java

목록 보기
8/16

JVM이란

Java Virtual Machine의 약자로, 자바 가상머신이다
자바가 OS에 구애 받지 않고 프로그램을 실행할 수 있도록 도와준다


Java 이전의 C언어와 C++ 언어는 컴파일 된 파일이 OS 별로 호환되지 않았다
이를 해결하기 위해 자바는 컴파일 시 바이트 코드까지만 실행하고 이후 과정은 OS가 진행하도록 함

  • C언어, C++언어 : 어셈블 코드까지 컴파일
  • Java : 바이트 코드까지 컴파일

예) Mac에서 자바 소스파일을 만들고 이를 윈도우에서 실행시키고 싶다면 윈도우용 JVM 만 있으면 된다


JVM은 스택 기반의 가상머신이다.

가상머신을 구현하는 방법은 크게 스택 기반과 레지스터 기반이 있다
둘은 피연산자를 저장하고 다시 가져오는 매커니즘에 차이가 있는데


스택 기반은 피연산자 2개를 스택에서 꺼내고 결과를 스택에 넣어준다.

  • 하드웨어를 직접 다루지 않아 덜 의존적
  • 다음 피연산자는 항상 스택의 TOP에 존재하므로 명령어 길이 짧아짐
  • 명령어의 수가 많아지고, 최적화 할 수 없음


    레지스터 기반은 명령어 수가 적고 최적화 할 수 있다, 반면 피연산자의 메모리 주소를 명시해야 해서 명령어의 크기가 커진다

자바 프로그램 실행 과정

  1. 프로그램이 실행되면 JVM은 OS로 부터 프로그램이 필요로 하는 메모리를 할당받는다
  2. 자바 컴파일러가 자바 소스코드를 읽어 바이트 코드로 변환시킨다
  3. Class Loader를 통해 바이트 코드 (class 파일) 들을 JVM으로 로딩한다
  4. 클래스 로더는 동적 로딩을 통해 필요한 클래스들을 로딩 및 링크하여 Runtime Data Area에 배치
  5. Runtime Data Area는 메모리에 올라온 바이트 코드를 실행 (인터프리터 방식, JIT 컴파일러 방식)

Class Loader

  • 클래스 파일 (바이트 코드) 들을 로드하고, 링크를 통해 배치하는 작업 수행
  • Runtime 시에 동적으로 클래스를 로드
  1. 로딩

    • 클래스 파일을 메소드 영역(클래스에 대한 정보가 저장되는 영역)에 저장
    • 클래스 파일은 부모 클래스 정보, 변수, 메소드 정보를 저장
  2. 링크

    1. 검증 : 읽어들인 클래스파일이 명시된대로 잘 구성되어있는지 확인
    2. 준비 : 클래스가 필요로 하는 메모리 할당
    3. 분석 : 심볼릭 메모리 레퍼런스(참조하는 대상의 이름만을 지칭)를 메소드 영역에 있는 실제 레퍼런스로 교체

Class Loader의 종류

  • 부트스트랩 클래스 로더 (최소한의 자바 클래스만을 로드)
  • 확장 클래스 로더
  • 시스템 클래스 로더 (우리가 만든 .class 파일 로드)

동작 방식

클래스 로더는 새로운 클래스를 로드해야 할 때

  • JVM 메소드 영역에 클래스가 로드되어 있는지 확인, 만약 로드되어 있다면 해당 클래스 사용
  • 로드 되어 있지 않다면 시스템 클래스 로더에 클래스 로드 요청 이를 확장 클래스로 요청 위임 -> 다시 부트스트랩에 요청 위임
  • 1. 부트스트랩 2.확장 3. 시스템 순서로 해당 클래스가 있는지 확인
  • 시스템 로더에도 없다면 ClassNotFoundException 발생

Execution 엔진

클래스 로더가 Runtime Data Area에 바이트 코드를 배치시키고 이것을 실행시키는 역할
바이트코드는 인간이 보기 편한 형태이기에 이를 기계가 실행할 수 있는 형태로 변경

  1. Interpreter
    • 자바 바이트 코드를 명령어 단위로 읽어서 실행, 한 줄 씩 수행 -> 느림
  2. JIT
    • 인터프리터 단점을 보완하기 위해 도입된 컴파일러
    • 인터프리터 방식으로 실행하다가 적절한 시점에 바이트 코드 전체를 컴파일함

JIT 컴파일러가 컴파일 하는 과정에 시간이 오래 걸리기에 JVM이 내부적으로 메서드가 얼마나 수행되는지 확인 후 일정 정도를 넘을 때만 컴파일 수행


+ Garbage collector가 있음. (따로 내용 다룸)

Runtime Data Area


프로그램을 수행하기 위해 OS 에서 할당 받은 메모리 공간

  • PC Register: Thread가 어떤 부분을 어떤 명령으로 실행해야 할지에 대한 기록을 함, 현재 수행중인 JVM 명령의 주소를 가짐 (스레드가 가지고 있는 레지스터는 저장된 상태)
  • JVM stack : 메소드 호출 시마다 메소드를 위한 공간이 생성되고, 수행이 끝나면 삭제를 함, 호출된 메소드의 매개변수, 지역변수 등 값을 임시로 저장
  • Native Method stack : 실제 실행할 수 있는 기계어로 작성된 프로그램을 실행시키는 영역, Java 언어 외의 언어로 작성된 코드를 위한 공간

  • Method Area (static 영역): 클래스 정보를 처음 메모리 공간에 올릴 때 초기화되는 대상을 저장하기 위한 메모리 공간
    1) 필드 정보 (맴버 변수 이름, 데이터 타입, 접근 제어자에 대한 정보)
    2) 메소드 정보 (메소드 이름, 리턴 타입, 매개변수, 접근제어자에 대한 정보)
    3) 타입 정보 (class인지 interface인지)
    - Runtime Constatnt Pool : 상수 자료형을 저장하여 참조하고, 중복을 막음
  • Heap : 객체를 저장하는 가상 메모리 공간, new 연산자로 생성된 객체와 배열 저장

정리

프로그램이 실행되면 JVM은 프로그램이 필요한 만큼 메모리를 할당받음, 자바 소스 코드 파일(.java) 은 컴파일러(javac) 에 의해 바이트 코드(.class)로 변환된다
이후 Class Loader를 통해 클래스 파일을 읽어들임, 동적 로딩을 통해 필요한 클래스들을 Runtime Data Area에 올림
Execution Engine은 메모리에 올라온 바이트 코드를 실행

profile
안녕하세요 ^^

0개의 댓글