- 자바 소스코드(.java)를 작성
우리가 일반적으로 작성하는 자바 코드
- 컴파일
자바 컴파일러(Java Compiler, javac)가 자바 소스파일을 컴파일 한다. 자바 컴파일러는 소스코드를 읽어들이고, 바이트코드(bytecode) 형태로 변환시킨다
- 클래스 파일 생성
컴파일된 바이트코드를 클래스 파일(.class)로 저장한다. 클래스 파일은 자바 프로그램에서 사용된다. 여러 클래스 파일은 하나의 패키지로 묶일 수 있다
- 클래스 로딩
클래스 파일을 사용하기 위해서는 먼저 해당 클래스를 JVM에 로딩해야 한다. JVM은 클래스 로더(Class Loader)를 사용하여 클래스 파일을 JVM 메모리 공간에 로드한다. 이 과정에서 클래스 파일 내부의 정적 변수, 메소드 등의 정보도 함께 로드된다
- 클래스 검증
JVM은 로딩된 클래스 파일이 올바른 자바 바이트코드인지 검증한다. 클래스 파일 내부의 구조와 명세에 따라 검증을 수행한다
- 준비
JVM은 클래스의 정적 변수를 초기화하고, 메소드를 준비한다. 준비 단계에서 메소드의 바이트 코드에 대한 레퍼런스를 준비한다
- JIT 컴파일
JVM은 필요에 따라 바이트코드를 실시간으로 기계어로 컴파일한다. 이를 JIT(Just-In-Time)컴파일 이라고 한다. JIT 컴파일은 실행 시간에 이루어지므로, 애플리케이션의 실행 속도를 향상시킨다
- 실행
JVM은 최종적으로 자바 바이트코드를 실행한다. JVM은 스택 기반의 가상 머신이므로 바이트 코드의 명령어를 스택으로 쌓아가며 실행한다. JVM은 스택 프레임을 생성하여 메소드 호출 정보를 저장한다
- 가비지 컬렉션
JVM은 메모리 관리를 위해 가비지 컬렉션(Garbage Collection)을 수행한다. 가비지 컬렉션은 더 이상 참조되지 않는 객체를 메모리에서 해제하여 메모리 누수를 방지한다
사진으로 보는 컴파일 과정
JVM 런타임 메모리 구조
Method 영역
JRE가 main()의 존재를 확인하면 메모리에 java.lang을 넣는다
그 후 JVM이 클래스들과 임포트 패키지들을 Method영역에 넣는다
여기서 static으로 작성한 변수와 메서드들고 여기에 들어간다
Stack 영역
main()내부에 있는 변수들과 메서드가 스택에 쌓이게 된다
해당 메서드와 변수들은 스택형식으로 호출되고 사라진다
Heap 영역
new키워드로 생성된 객체와 배열이 저장되는 영역이다
Object타입의 데이터가 저장된다