[Java] JVM 구조 & Java 프로그램 컴파일 및 실행 과정

Kim Hyen Su·2024년 3월 8일
0

📐Java

목록 보기
2/18
post-thumbnail

참조 포스팅

📐JVM 구조

JVM : 자바 가상 머신의 약자입니다.

JVM은 자바 애플리케이션을 클래스 로더를 통해 읽어들여 자바 API와 함께 실행하는 것입니다.

JVM의 구조는 class loader, execution engine, runtime data area, JNI, native method library로 구성되어 있습니다.

  • 클래스 로더 : JVM 내로 클래스를 로딩하고, 링크를 통해서 배치하는 작업을 수행하는 모듈
  • 실행 엔진 : 바이트 코드를 실행시키는 역할
    • 인터프리터 : 바이트 코드 명령어 하나씩 실행.
    • *JIT 컴파일러 : 인터프리터 효율을 높이기 위한 컴파일러
    • GC : 힙 영역에서 사용되지 않는 메모리를 정리하고 관리하는 역할
  • 런타임 데이터 영역 : 프로그램 실행 중 사용되는 JVM의 메모리 공간
    • PC Register : Thread가 시작될 때 생성되며 현재 수행중인 JVM 명령어의 주소를 가지고 있습니다.
    • Stack Area : 지역변수, 함수 등이 생성되는 여역, 실제 객체는 Heap 메모리에 할당이 되고 해당 참조만 Stack에 저장됩니다.
    • Heap Area : 동적으로 생성된 객체와 배열이 저장되는 곳으로 GC의 대상 영역입니다.
    • Method Area : 클래스 멤버 변수, 메서드 정보, Type 정보, Constant Pool, static, final 변수 등이 생성됩니다. 상수 풀은 모든 Symbolic Reference를 포함하고 있습니다.
  • JNI(Java Native Interface) : 자바 애플리케이션에서 C, C++, 어셈블리어로 작성된 함수를 사용할 수 있는 방법을 제공해줍니다. Native 키워드를 사용하여 메서드를 호출합니다. 대표적인 메서드는 Thread의 currentThread() 입니다.
  • Native Method Library : C, C++로 작성된 라이브러리입니다.

📐 자바 컴파일 과정

  1. 개발자가 자바 소스코드(.java)를 작성합니다.

  2. 자바 정적 컴파일러(Javac)가 자바 소스파일을 번역합니다. 이 때 나오는 파일은 자바 바이트 코드(.class)로 아직 컴퓨터가 읽을 수 없는 코드지만 JVM이 이해할 수 있는 코드입니다. 바이트 코드의 각 명령어는 1바이트 크기의 opcode와 추가 피연산자로 구성되어 있습니다.

  3. 컴파일된 바이트 코드를 JVM 안에 클래스 로더에게 전달합니다.

  4. 클래스 로더는 프로젝트 실행에 필요한 클래스들을 동적으로 로딩 및 링크하여 런타임 데이터 영역(Runtime Data Area), 즉 JVM의 메모리에 올립니다.

    • 클래스 로더 세부 동작
      • 로드 : 클래스 파일을 가져와서 JVM 메모리에 로드합니다.
      • 검증 : 자바 언어 명세(Java Language Specification) 또는 JVM 명세에 명시된 대로 구성되어 있는지 검사합니다.
      • 준비 : 클래스가 필요로 하는 메모리를 할당합니다.(필드, 메서드, 인터페이스 등)
      • 분석 : 클래스의 상수 풀 내 모든 심볼릭 레퍼런스를 다이렉트 레퍼런스로 변경합니다.
      • 초기화 : 클래스 변수들을 적절한 값으로 초기화합니다.(static 필드)
  5. 실행엔진은 JVM 메모리에 올라온 바이트 코드들을 명령어 단위로 하나씩 가져와서 실행합니다. 이 때, 실행 엔진은 두가지 방식으로 변경합니다.

    • 인터프리터 방식 - 한줄씩 해석 후 실행.
    • JIT 컴파일러(Just-In-Time Compiler) 방식 - 일괄적으로 바이트 코드를 운영체제에 맞게 변경 후 실행
profile
백엔드 서버 엔지니어

0개의 댓글