본문 바로가기
컴퓨터/Java

[JVM] JVM 동작 과정 - | 클래스로더, 실행엔진, 가비지 컬렉션

by 버니케이 2024. 12. 19.
반응형

 

 

JVM 동작 선요약

1. 컴파일된 자바를 클래스 로더를 통해 읽으면, 클래스 로더가 바이트코드를 검증하고 메모리에 올림

 

2. 클래스 로더가 할일을 끝낸다면 정적변수들이 기본값으로 설정된 후에 정적 초기화 블록이 실행됨 (초기화)

 

3. 그 후, 초기화가 끝나면 JVM 실행엔진이 작동 : 메모리에 올라간 바이트코드를 기계어로 번역해서 실행

 

4. 실행되는 동안 가비지 컬렉션이 힙메모리를 돌면서 사용되지 않는 객체들을 정리

 


클래스로더

컴파일된 클래스 파일들을 JVM 안에 있는 클래스 로더가 읽음.

 

클래스로더는 컴파일된 바이트코드들을 동적로딩 한 다음에  메서드 영역에 넣음

 

=> 클래스 로더는 클래스 파일을 로드하고 메모리에 올리는 일을 하는애

 

클래스로더 - 동적로딩

클래스 파일을 로드한다 = 동적로딩

 

동적로딩은 프로그램 실행 중에 필요한 클래스를 찾아서 로드하는 과정인데,

필요한 클래스를 찾는다는 건
만약 a.class 파일이 b.class 파일을 import 한다면,
a.class 파일을 로드할 때 JVM은 필요에 따라 b.class 파일도 로드한다.

 

근데 이걸 프로그램 실행 중에 한다..

 

 

클래스로더 - 메모리영역에 넣기 (메모리 할당)

클래스 로더가 필요한 클래스들을 전부 다 로드했다면 JVM 메모리 상에 올려야 한다.

 

JVM 은 가상머신이여서 JVM 만의 독립적인 메모리 영역이 있는데,

그 메모리 영역은 메서드영역, 힙영역, 스택영역으로 구성됨.

이 셋 영역중에 클래스는 메서드영역에 올라감.

 

초기화

 

이 초기화 단계도 클래스로더가 도는거...

초기화 단계에서는 static 변수들이 메서드영역에 들어가고 정적 초기화 블록이 실행됨.
(static 변수 == 정적 변수)
(정적 초기화 블록 == static{})

 

 

초기화- 정적 초기화

정적 초기화 == 변수에 처음으로 값을 할당하는 것

 

일반 변수들(기본형, 참조형)은 객체가 생성될 때 해당 객체의 초기값으로 초기화되는데
근데 static 변수들은 클래스 수준에 있기 때문에 프로그램이 실행될 때 초기화 된다.

 

 

그니까 초기화단계에서는
static 변수들을 static{} 이라는 정적 초기화 블록 안에 모아놓고 초기화 후
static 변수들에 값을 할당해서 사용할 준비를 하게 만듦

=> 클래스로더가 하는일은 필요한 모든 클래스들과 static 변수들을 메서드영역에 넣는 작업

 

 

실행엔진

메서드영역에 모든 데이터를 넣었다면 JVM의 실행엔진이 작동을 시작함.

 

실행엔진은 JVM 의 메모리 영역과 스택 영역을 돌면서 실행.

 

처음에는
JVM의 실행 엔진은 메서드 영역의 클래스 파일을 읽고, 프로그램이 시작될 때 main() 메서드부터 실행함.
그리고 main() 메서드 안에서 다른 메서드나 클래스 파일을 호출하면 해당 메서드들이 스택영역에 추가...
(클래스 파일은 어차피 메서드영역에 있으니, 거기 안에서 정의된 메소드를 찾아서 스택영역에 쌓음)

 

호출된 메서드들이 순차적으로 실행되고, 실행이 완료되면 호출 스택에서 제거되고....
이런 식으로 JVM은 프로그램을 실행하고 메서드 호출을 관리함

 

 

실행엔진 - 인터프리터, JIT 컴파일러

근데 이 작업은

실행스택이 컴퓨터한테 알려주는 작업이라서
그니까 .class 를 0101010 로 바꿔서 알려줘야 컴퓨터가 알아먹음

 

이 작업은 인터프리터 방식이나 JIT 컴파일러를 통해 번역이 됨

 

인터프리터 방식은 한줄한줄 번역하면서 읽는거고
JIT 컴파일러는 소스를 미리 읽고 번역하는 것

 

프로그램이 완전 처음 실행될 때는 인터프리터 방식으로 작동
그다음부터는 인터프리터로 번역 중에 특정 코드 블록이 자주 반복된다면 JIT 컴파일러가 식별해서 기계어로 컴파일해놓음
그래서 실행속도가 빨라짐

 


가비지 컬렉션

JVM의 실행엔진이랑은 관련없음

클래스로더가 돌거나 실행엔진이 돌거나 뭐 다른 작업들을 하거나 할 때 백그라운드에서 계속 작동

 

가비지 컬렉션이 하는 일은
JVM 메모리영역 중 힙메모리 영역을 돌면서 더 이상 참조되지 않는 객체들을 지워버리는 역할을 함.

 

 

가비지컬렉션은 힙메모리에서 작동함.
왜냐면 스택메모리는 지역변수, 함수 매개변수들이 저장되는 곳인데 얘네들은 함수 종료되면 자동으로 메모리 해제됨.
결론은 스택메모리는 가비지컬렉션이 필요하지 않음.

반응형

댓글