[Java] 자바 프로그램 동작 과정

박상혁·2023년 4월 9일
0

Java

목록 보기
4/10
post-thumbnail

개요

자바 어플리케이션의 동작 과정을 JVM 내부의 메모리 구조, Class Loader, Execution Engine 3개의 유기적인 동작 흐름과 함께 자세히 살펴봅니다.
SpringBoot의 실행 방식을 알기 위해 꼭 필요한 과정이라 생각합니다.

목차

  1. java.exe 실행
  2. JVM 실행

본론

Java.exe 실행

Java 어플리케이션을 실행하기 위해서는
JRE에 내장되어있는 자바 실행기(java.exe)를 통해 클래스 파일(.class)을 실행해야합니다.
JRE는 다음과 같은 사전 준비를 거칩니다.

  • 클래스 파일 내 main method가 존재하는지 확인
  • 기타 이상없는지 확인

이후 JVM을 부팅시킵니다.

JVM 구동 및 전처리


처음 JVM이 시작할 때

  • Runtime Data Area가 생성되고 안에 Method, Heap 영역이 할당됩니다.
  • BootStrap Class Loader가 JVM 실행에 필요한 클래스들을 Method영역으로 Loading합니다.

해당 과정을 마친 후
저희가 실행하고자 하는 java 어플리케이션(.class)을 실행합니다.

  • System Class Loader를 통해 저희가 작성한 클래스, import된 패키지에 속한 클래스들을 Method 영역으로 로딩합니다.
  • 로딩, 링크, 초기화 과정을 거친 후 해당 클래스의 main method를 실행하여 Stack영역에 적재합니다.

인터프리터 및 JIT

main 메서드 실행


인터프리터 및 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와는 다른 개념)

종료

  • main method의 '}'를 만나게 되면 main stack frame이 소멸되면서 모든 stack frame이 제거되고 JRE가 JVM을 종료하고 JRE 자체도 사라지게 됩니다.
  • 일부 쓰레드가 임의로 Runtime 클래스의 종료 메서드, 중지 메서드 혹은 클래스 시스템의 종료 메서드를 호출하면 JVM의 종료, 중지 작업이 Security Manager에 의해 허용됩니다.

실행 엔진

JVM 내부에 있는 프로그램으로써 바이트 코드를 Native 코드로 변환하는 역할을 담당합니다.
java 프로그램이 실행되면서 JVM 메모리 영역에 쌓인 Data영역(Method영역의 Bytecode)들은 실행 엔진에 의해 처리되어 Native 코드로 변환됩니다.
그 후 운영체제가 이를 처리합니다.

요약

참조

Java 프로그램의 실행원리(feat. JVM) - ikjo
How the JVM Locates, Loads, and Runs Libraries - Oleg Šelajev
초보 Spring(Java) 개발자를 위한 완전 기초 지식(이론편)

profile
개발 노트

0개의 댓글