자바 어플리케이션의 동작 과정을 JVM 내부의 메모리 구조, Class Loader, Execution Engine 3개의 유기적인 동작 흐름과 함께 자세히 살펴봅니다.
SpringBoot의 실행 방식을 알기 위해 꼭 필요한 과정이라 생각합니다.
- java.exe 실행
- JVM 실행
Java 어플리케이션을 실행하기 위해서는
JRE에 내장되어있는 자바 실행기(java.exe)를 통해 클래스 파일(.class)을 실행해야합니다.
JRE는 다음과 같은 사전 준비를 거칩니다.
이후 JVM을 부팅시킵니다.
처음 JVM이 시작할 때
Method
, Heap
영역이 할당됩니다.Method
영역으로 Loading합니다.해당 과정을 마친 후
저희가 실행하고자 하는 java 어플리케이션(.class)을 실행합니다.
Method
영역으로 로딩합니다.main method
를 실행하여 Stack영역에 적재합니다.
인터프리터 및 JIT를 통해 기계어로 변환하여
기계어 코드를 읽고 JVM이 실행합니다.
최초의 실행은 main method 입니다.
main method가 실행되기 위해서 stack frame이 stack 영역에 최초로 할당됩니다. (정확히는 '{' 만날 때 frame이 생김)
이후 main stack frame 내에는 main 메서드와 관련된 지역 변수, 메서드의 매개변수 공간이 할당됩니다.
JVM은 자바 Thread를 생성합니다. 위의 main method가 실행되는 과정도 하나의 Thread를 만들어 그 안에서 실행합니다.
Thread를 통해 여러 작업을 동시에 처리하며, 동기화된 코드 실행, I/O 작업 등을 수행할 때 유용합니다.
기계어 코드를 읽고 JVM이 실행하면서 메모리 할당
, 해제
, Garbage Collector
등을 사용하여 메모리 자원을 효율적으로 관리합니다.
main 메서드 안에 또다른 메서드를 호출 시
그에 해당하는 stack frame이 stack 영역에 쌓이게 됩니다.
이렇게 stack frame이 쌓이고 지워짐을 반복하며 어플리케이션의 연산을 수행합니다.
frame : stack 영역에 쌓은 하나의 메모리 영역. 프로시저 호출이나 메서드 호출 시 이전 코드 실행 주소, 인자 값 등을 백업시킴.
<stack frame에 관련된 자세한 내용은 JVM 포스팅을 참조>
중간에 new를 통해 객체를 생성하는 작업을 한다면
heap 영역에 저장되며 이를 참조하게 됩니다.
<heap 영역의 동작 방식에 관련된 자세한 내용은 JVM 포스팅 참조>
Runtime때 계속해서 필요한 Class를 ClassLoader가 가지고와서 배치합니다.
런타임 중에 동적으로 저장된 클래스를 JVM 위에 탑재, 사용하지 않는 클래스를 메모리에서 삭제(GC와는 다른 개념)
JVM 내부에 있는 프로그램으로써 바이트 코드를 Native 코드로 변환하는 역할을 담당합니다.
java 프로그램이 실행되면서 JVM 메모리 영역에 쌓인 Data영역(Method영역의 Bytecode)들은 실행 엔진에 의해 처리되어 Native 코드로 변환됩니다.
그 후 운영체제가 이를 처리합니다.
Java 프로그램의 실행원리(feat. JVM) - ikjo
How the JVM Locates, Loads, and Runs Libraries - Oleg Šelajev
초보 Spring(Java) 개발자를 위한 완전 기초 지식(이론편)