[Java] 자바 컴파일 과정, JVM

호호빵·2022년 9월 21일
0

Java

목록 보기
9/19

기본 배경

  • Java의 큰 특징 중 하나가 어느 하드웨어(CPU), 어느 운영체제이든 상관없이 컴파일된 코드가 플랫폼 독립적이라는 것(작성한 소스 변경 없이 실행 가능)
  • 이러한 특징을 구현하기 위해서는 JVM이 필요
    JVM : 컴파일된 코드를 실행시켜주는 가상의 컴퓨터
  • JVM은 H/W와 OS 위에서 실행되기 때문에 JVM자체는 플랫폼에 종속적
    즉, 플랫폼에 따라 호환되는 JVM을 실행시켜줘야 함
    		         Program  
      Program 		  J V M     <-
        O S	 		   O S
       H / W 		  H / W
    
    <일반 프로그램>   <Java 프로그램>

자바 컴파일 과정

  • 첫번째 사진처럼 이해했다가 두번째 그림을 보고 확실히 이해할 수 있었다.
    (221205에 추가)
  1. 텍스트 파일인 자바 소스코드 작성

  2. 자바 컴파일러가 자바 소스파일을 컴파일
    (이때 나오는 파일은 자바 바이트 코드(.class)파일로 아직 컴퓨터가 읽을 수 없는 자바 가상 머신이 이해할 수 있는 코드)

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

  4. 클래스 로더는 동적로딩(Dynamic Loading)을 통해 필요한 클래스들을 로딩 및 링크하여 JVM의 메모리(Runtime Data area)에 올림
    • 클래스 로더 세부 동작

  5. 실행엔진(Execution Engine)은 JVM 메모리에 올라온 바이트 코드들을 명령어 단위로 하나씩 가져와서 기계어로 변경 (두가지 방식)

  6. 기계어로 번역됨

  7. main() 메소드 찾아서 실행
  • 실행문 : 변수 선언, 값 저장, 메소드 호출에 해당하는 코드

JVM의 동작원리 기본개념

  • 클래스 로더
  • 런타임 데이터 영역
  • 실행 엔진

클래스 로더(Class Loader)

  • 컴파일된 .class 파일을 동적으로 JVM 메모리에 로딩하는 역할

  • JVM이 동작하다가 클래스 파일을 참조하는 순간 동적으로 읽어서 메모리에 로드되면서 JVM에 링크 됨

  • 컴파일된 클래스 파일은 Loading -> Linking -> Initializing 단계를 거쳐 JVM에서 사용할 수 있게 됨

  • 클래스 로더가 .class 파일을 읽고 데이터를 Method Area영역에 저장

  • 메소드 영역에 저장하는 데이터들
        - FQCN(Fully Qualified Class Name) : package를  포함한 Class이름
            → java.lang.String
    
        - 클래스 | 인터페이스 | 이넘
        - 메소드와 변수


클래스 로더 세부 동작

  • 로드
    : 클래스 파일을 가져와서 JVM의 메모리에 로드
    : 클래스 파일을 읽고 그에 따라 적절한 바이너리 데이터를 만들고 메소드 영역에 저장하는 동작 수행
    : 이 과정에서 클래스 파일이 JVM 스펙에 맞는지 확인하고 Java Version도 확인

  • 검증
    : 자바 언어 명세(Java Language Specification) 및 JVM 명세에 명시된 대로 구성되어 있는지 검사

  • 준비
    : 클래스가 필요로 하는 메모리를 할당 (static 변수와 기본값, 필드, 메서드, 인터페이스 등등)

  • 분석
    : 클래스의 상수 풀 내 모든 심볼릭 레퍼런스를 다이렉트 레퍼런스로 변경

  • 초기화
    : 클래스 변수들을 적절한 값으로 초기화 (static 필드)
    : 링크(link)의 준비(prepare) 단계에서 확보한 메모리 영역에 클래스의 static 값들을 할당
    : SuperClass 초기화와 해당 클래스의 초기화 진행


런타임 데이터 영역 (데이터 저장 영역)

  • java.exe로 JVM이 시작되면 운영체제에서 할당받은 메모리 영역(Runtime Data Area)을 다음과 같이 세부 영역으로 구분해서 사용
    → 스태틱 영역 : 클래스와 static 친구들
    → 스택 영역 : 메서드들
    → 힙 영역 : 객체(Instance)들

Method Area (Static 영역)

  • 클래스들을 클래스로더로 읽어 클래스별로 분류해서 저장
  • JVM이 시작할 때 생성, 모든 스레드가 공유하는 영역

JVM 스택 영역

  • 각 스레드마다 하나씩 존재하며 스레드가 시작될때 할당됨
  • 메소드를 호출하면 프레임 추가(push), 메소드가 종료되면 프레임 제거(pop) 수행(지역변수, 메소드 등이 할당)

Heap 영역

  • 객체와 배열이 생성되는 영역
  • 생성된 객체와 배열은 JVM 스택 영역의 변수나 다른 객체의 필드에서 참조

Garbage Collector

  • GC는 힙 영역에서 사용하지 않는 객체들을 제거하는 작업(객체를 제거하는 작업이 필요한 이유는 개발자가 메모리를 직접 해제해줄 수 없는 언어이기 때문)
  • GC 수행시 시스템이 멈추기 때문에 의도치 않은 장애의 원인이 될 수 있습니다. 따라서 이를 위해 힙 영역을 조정하는 것을 GC 튜닝이라고 하고 JVM 메모리는 절대 마음대로 조정해선 안됩니다.

실행 엔진(Excution Engine)

  • 바이트 코드를 기계가 실행할 수 있는 기계어로 변경
  • 클래스 로더를 통해 런타임 데이터 영역에 배치된 바이트 코드를 명령어 단위로 읽어서 실행(CPU가 기계 명령어를 하나씩 실행하듯이)

인터프리터

  • 바이트 코드 명령어를 하나씩 읽어서 해석하고 실행
    (하나하나의 실행은 빠르나, 전체적인 실행 속도가 느림)

JIT 컴파일러(Just-In-Time Compiler)

  • 인터프리터의 단점을 보완하기 위해 도입된 방식으로 바이트 코드 전체를 컴파일하여 바이너리 코드로 변경하고 이후에는 해당 메서드를 더이상 인터프리팅 하지 않고, 바이너리 코드로 직접 실행하는 방식
  • 하나씩 인터프리팅하여 실행하는 것이 아니라 바이트 코드 전체가 컴파일된 바이너리 코드를 실행하는 것이기 때문에 전체적인 실행속도는 인터프리팅 방식보다 빠름


자바 컴파일 과정
클래스 로더
우연희 튜터님 강의 자료 - 221205에 추가

profile
하루에 한 개념씩

0개의 댓글

관련 채용 정보