본문 바로가기

TIL(Today I Learned)

TIL-231024(자바 프로그램 실행 과정)

📝오늘 공부한 것

  • 자바 프로그램 실행 과정 공부
  • 커리어톤 참여하기
  • 프로그래머스 문제풀기

📌 자바 프로그램 실행 과정

📍 Java Compiler

자바 소스파일을 JVM이 해석할 수 있는 자바 바이트 코드(.class)로 변경한다.

일반적인 윈도우 프로그램의 경우, Compile이후 Assembly 언어로 구성된 파일이 생성된다.

 

📍 Compile

컴파일은 사람이 이해하는 언어를 기계어로 바꾸는 과정이다.

=원시코드에서 목적코드로 바꾸는 과정

일반적으로 소스파일을 컴파일한 파일을 목적파일이라고 하는데 C, C++과 같은 언어는 목적파일이 바이너리 코드의 형태를 갖는다. 하지만 자바에서는 바이너리 코드가 아닌 바이트코드를 가진 바이트파일로 변환이 된다. 

 

- 소스파일 : 개발자가 작성하는 고레벨언어인 소스코드로 구성된 파일.   ex) *.java, *.c

- 목적파일 : 소스파일을 컴파일해서 생긴 파일.   ex) 바이트코드, 바이너리코드

 

https://kingofbackend.tistory.com/123

📍 자바 바이트 코드

JVM이 이해할 수 있는 언어로 변환된 자바 소스 코드

자바 컴파일러에 의해 변환되는 코드의 명령어 크기가 1바이트라서 자바 바이트 코드라고 불린다.

이러한 자바 바이트 코드의 확장자는 .class이며 자바 바이트코드는 자바 가상 머신만 설치되어 있으면, 어떤 운영체제에서라도 실행될 수 있다.

 

📍 JVM (Java Virtual Machine)

자바 바이트 코드(.class)를 운영체제에 맞는 시스템 명령어로 번역하여 실행한다.

write once, run everywhere 즉, OS마다 따로 코드를 작성해야 하는 번거로운 작업이 Java가 플랫폼에 독립적일 수 있게 만들어준다.

자바는 플랫폼에 독립적이고, JVM은 플랫폼에 종속적이다.

 

https://kingofbackend.tistory.com/123

 

📍 Class Loader

클래스를 JVM의 메모리에 로드한다. Runtime 시에 동적으로 클래스를 로드한다.

Loading된 클래스들을 Runtime Data Area에 배치된다.일반적인 윈도우 프로그램의 경우 Load 과정은 OS가 주도한다.

클래스에 필요한 메모리를 할당하고, 클래스에서 정의된 필드, 메서드, 인터페이스들을 나타내는 데이터 구조를 준비한다.

 

📍 Execution Engine

두가지 방식을 이용하여 데이터 영역에 배치된 바이트코드를 실행한다.(Interpreter, JIT Compiler)

데이터 영역에서 사용하지 않는 메모리를 해제한다.(Garbage Collector)

 

1. Interpreter

  • 소스코드의 각 행을 연속적으로 분석하며 실행한다.
  • 때문에 일반적으로 각 행마다 실행하는 인터프리터보다는 컴파일러가 더 빠르다.

 

2. JIT Compiler

  • Just In Time. 프로그램을 실제 실행하는 시점에 번역하는 컴파일 기법이다.
  • 자바 컴파일러(javac)는 자바 소스코드를 바이트코드로 변환하고 JIT는 변환된 바이트코드를 해석하고 실행한다.
  • 같은 코드를 매번 해석하지 않고 실행할 때 컴파일하면서 코드를 캐싱한다. 사전에 정의된 임계치에서 시작하여 호출될 때마다 감소시키는 방식으로 자주 사용되는 메서드를 찾는다. 자주 사용되는 메서드는 저장해서 해석하지 않고 바로 실행시키는 방식으로 성능을 향상시킨다.

3. Garbage Collector

  • 메모리 영역의 메모리를 관리한다.
  • 메모리가 부족할 때 Garbage를 메모리에서 해제시켜 다른 용도로 사용할 수 있게 해주는 프로그램을 말한다.
모든 코드는 초기에 인터프리터에 의해 시작되고, 해당 코드를 충분히 많이 사용할 경우 JIT Compiler에서 컴파일을 수행하게 된다. 초기에 인터프리터 방식으로 바이트 코드를 변환하면서 그 코드를 캐싱하여, 같은 함수가 여러번 불릴 때 매번 코드가 생성되는 것을 방지한다.
이렇게 컴파일된 코드를 네이티브 코드라고 하는데 네이티브 코드는 캐시에 보관되기 때문에 한번 컴파일된 코드는 빠르게 수행될 수 있다.

 

https://github.com/yeoseon/tip-archive/issues/74

 

📍 Runtime Data Area

JVM이 프로세스로써 수행되기 위해 OS로부터 할당받는 메모리 영역이다. 저장목적에 따라 5개로 나눌수 있다.

PC Register, Stack, native method stack은 쓰레드마다 하나씩 생성되고,

Heap, Method Area는  모든 쓰레드가 공유해서 사용한다.

 

Method Area

  • 클래스 정보를 처음 메모리 공간에 올릴 때 초기화되는 대상을 저장하기 위한 메모리 공간
  • 클래스 정보, 변수 정보, Method 정보, static변수 정보, 상수 정보 등이 저장되는 영역

 

Heap

  • 프로그램 상에서 데이터를 저장하기 위해 런타임 시 동적으로 할당하여 사용하는 메모리 영역
  • new 연산자로 생성된 인스턴스와 객체가 저장되는 구역, Garbage Collection 대상이다.

 

PC Register

  • CPU의 Register와 역할이 비슷하다. 현재 수행 중인 JVM명령의 주소 값이 저장된다.
  • 어떤 부분을 어떤 명령으로 실행할지를 기록하며 현재 명령과 주소를 저장한다.

 

Stack

  • Method안에서 사용되는 값들(매개변수, 지역변수, 리턴 값 등)이 저장되는 구역, 메서드가 호출될 때 LIFO로 하나씩 생성되고, 메서드 실행이 완료되면 LIFO로 하나씩 지워진다.

 

Native Method Stack

  • 자바 외의 언어로 작성된 네이티브 코드를 위한 스택이다.

 

⭐ 자바프로그램 실행과정

1. 프로그램이 실행되면 JVM은 OS로부터 이 프로그램이 필요로 하는 메모리를 할당박는다.
2. 자바 컴파일러(javac)가 자바 소스코드(.java)를 읽어들여 자바 바이트코드(.class)로 변환시킨다.
3. Class Loader를 통해 .class파일들을 JVM에 로딩한다.
4. 로딩된 .class파일들을 Execution Engine의 Interpreter와 JIT Compiler를 통해 해석된다.
5. 해석된 바이트코드를 Runtime Data Areas에 배치되어 실질적인 수행이 이루어진다.

 

 

 

 

 

References :

자바의 정석 3판(남궁성)

https://pienguin.tistory.com/entry/JAVA-%EC%9E%90%EB%B0%94-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8-%EC%8B%A4%ED%96%89-%EA%B3%BC%EC%A0%95-%EB%B0%8F-%EA%B8%B0%EB%B3%B8-%EA%B5%AC%EC%A1%B0

https://velog.io/@pond1029/JVM

https://github.com/yeoseon/tip-archive/issues/74