자바 컴파일과 실행순서

kmb·2022년 1월 4일
0

자바

목록 보기
2/31
post-thumbnail

이클립스를 이용해서 Java Project 파일을 만들면 그 안에는
아래 그림처럼 5가지 파일이 만들어진다.( .setting / bin / src / .classpath / .project )

bin폴더는 실행파일이 모여있는 폴더이다. 내부에는 컴파일 된 .class 파일이 있다.

 

자바소스파일(.java)이 실행되는 과정

1) 우리가 코드를 작성하고 ctrl+s 눌러서 저장을 하는 순간에 자연어인 자바 소스파일(.java)자바 컴파일러(javac.exe)에 의해서 --> 바이트 코드(Byte Code)로 이루어진 바이트 코드 파일(.class)로 변환된다. (아직 컴퓨터가 읽을 수 없는 상태)

 

2) JVM은 바이트 코드(Byte code)로 이루어진 .class 파일을 Class Loader를 이용해서 로드하고, 링크를 통해 배치하는 작업을 수행한다. 또한 런타임 시에 동적으로 클래스를 로드한다. Class Loader는 크게 3가지 영역으로 나뉜다.

  • Loading
    .class 파일을 읽고 바이트 코드(Byte code)를 OS에서 할당 받은 메모리 영역인 JVM 메모리 영역(RunTime Data Area) 내부의 Method Area(=Class 영역)에 저장한다. 또한 .class파일이 RunTime Data Area에 Load 된 후에는 JVM이 heap 메모리 영역에 .class 파일이 나타내는 유형의 객체를 생성한다.
  • Linking
    검증(verification), 준비(preparation), 해결(resolution) 3가지를 수행한다.

    검증(verification) : 유효한 컴파일러에 의해 생성되었는지 확인하여 .class 파일의 정확성을 보장한다. 만약 검증에 실패한다면 java.lang.VerifyError 가 발생한다.
    준비(preparation) : Static Field에 메모리를 할당하고, 메모리를 할당한 변수 타입에 따라 default 값으로 초기화한다.
    해결(resolution) : 클래스파일에 참조된 클래스들을 로드한다. 이때 참조객체들은 Symbolic References를 통해 참조하며 Symbolic References는 Constant Pool 에 저장되어있다. 클래스들이 RunTime Data Area에 load 되면 Constant Pool 내부의 Symbolic References를--> Direct References로 전환시킨다. (즉 실제 메모리값으로 주소를 변경한다.)

  • Initialization : Static Field의 값들을 정의한 값으로 초기화 한다.

 

3) Class Loader에 의해 .class 파일이 JVM 메모리 영역(RunTime Data Area)에 적재가 된다. 이때 RunTime Data Area는 세그멘테이션 구조로 5가지 영역으로 구분된다.

  • Method 영역(=Class 영역 = Static 영역)
    모든 스레드에게 공유된다.
    클래스 이름, 부모 클래스 이름, 메서드, 변수 등의 클래스 정보들을 저장. (전역변수 포함)
    static이 붙은 것들은 모두 이 메모리에 할당된다.
    main 함수(스레드)에도 static이 붙어있는데, 자바가 실행될 때 main 메서드를 찾아서 바로 Method 영역에 할당하고 이 값들은 JVM이 종료될 때까지 유지된다.

  • Heap 영역
    모든 스레드에게 공유된다.
    동적으로 할당되는 변수들(레퍼런스 변수)이 Heap영역에 할당된다.
    Garbage Collector(GC)를 통해서 만약 객체에 참조되지 않는 변수가 있다면 GC가 삭제한다.

  • Stack 영역
    각 스레드마다 1개씩 생성된다.
    스레드에 대해서 JVM은 메서드를 호출시마다 각각의 Stack 프레임을 생성한다. 메서드 내부의 지역변수, return 값, 매개변수를 Stack 프레임에 임시로 저장하고 스레드가 끝나면 JVM에 의해서 RunTime Stack이 소멸된다. (LIFO구조)

  • PC Register
    각 스레드마다 1개씩 생성된다.
    현재 실행되는 부분의 명령과 주소를 저장.
    즉 스레드가 어떤 부분을 어떤 명령으로 실행할지에 대한것을 기록하는 부분으로서 현재 수행중인 JVM 명령의 주소값이 저장된다.

  • Native Method Stack Area
    각 스레드마다 1개씩 생성된다.
    Java 외의 다른 언어에서 제공되는 메서드들이 저장되는 공간. JNI(Java Native Interface) 라는 표준 규약을 제공한다.

 

4) Execution Engine은 JVM 메모리 영역에 적재된 Byte code로 이루어진 .class 파일을 기계어로 변경하여 명령어(instruction) 단위로 실행한다. 이때 3가지 영역으로 구분된다.

  • 인터프리터(Interpreter)
    Byte code를 1줄씩 해석하고 실행한다.

  • Just In Time Compiler (JIT Compiler)
    전체 Byte code를 필요한 만큼 쪼개서 실시간으로 실행가능한 상태로 컴파일한다.

  • Garbage Collector
    참조되지 않은 객체들을 삭제하고 삭제된 객체의 메모리를 반환한다. 또한 Heap 메모리를 재사용한다.

JVM에 의해서 바이트 코드(ByteCode)를 OS가 이해할 수있는 기계어로 해석되므로 OS의 종류에 종속되지 않는다.

 

출처

profile
꾸준하게

0개의 댓글