JVM이란 JAVA Virtual Machine을 이르는 말이야.
JVM은 코드를 실행하고 해당 코드에 대해 런타임 환경을 제공하는 소프트웨어 프로그램에 대한 사양이라고 하는데
그냥 쉽게 말해서 자바 프로그램을 실행하는 방법이라고 보면 돼.
[실행 과정]
실행자가 자바 소스파일을 실행시키면 JAVA컴파일러가 .java파일을 .class파일로 변환시켜줘.
이렇게 변환된 class파일은 class loader를 만나게 되는데, 이 녀석은 class파일을 JVM에 할당된 메모리에 적재해주는 역할을 하고 있어.
<Class Loader>
JVM이 시작되면 3개의 Class Loader가 사용돼.
1. 부트스트랩 클래스 로더
2. 확장 클래스 로더
3. 시스템 클래스 로더
<JVM 메모리 구조>
방금 전에 class loader가 class파일을 메모리에 적재한다고 했지? 이제 JVM메모리에 어떤 영역들이 있는지 알아보자.
JVM안에 있는 메모리는 Runtime DataArea라고 명칭해. 그 안에는 5개의 영역으로 나뉘지.
1. Method Area - 메소드 영역
- 클래스 정보를 처음 메모리 공간에 올릴 때 초기화되는 대상을 저장하기 위한 메모리 공간.
- 필드 정보, 메소드 정보, Type 정보, Constant Pool, static 변수, final class 변수 등 생성.
클래스 멤버 변수의 이름, 데이터 타임, 접근 제어자 등 필드정보와 메소드의 이름, 리턴 타입, 파라미터, 접근 제어자 같은 메소드 정보, Type정보(Interface인지 class인지), Constant Pool(상수 풀 : 문자 상수, 타입, 필드, 객체 참조가 저장됨), static 변수, final class 변수등이 생성되는 영역이야.
특별히 메소드 영역에는 Runtime Constant Pool 이라는 별도의 관리영역도 존재해. 이 공간은 상수 자료형을 저장해서 참조하고 중복을 막는 역할을 수행하지!
2. Stack Area - 스택 영역
- 임시로 할당되었다가 메소드를 빠져나가면 바로 소멸하는 것이 특징.
스택영역에는 지역변수와 매개변수가 저장돼. 즉 각종 형태의 변수나 임시 데이터, 스레드나 메소드의 정보를 저장하지.
또 메소드를 호출 할 때마다 각 스택이 생성이 돼.
3. Heap Area - 힙 영역
new 키워드로 생성된 객체와 배열이 생성되는 영역이야.
보통 스택영역에 저장되는 지역변수, 매개변수와는 달리 힙영역에 보관되는 메모리는 호출이 끝나도 사라지지 않고 유지 돼.
계속해서 쌓이다보면? 해당 메모리가 주소를 잃어버리는데, 이 때 Garbage Collector가 그런 쓰레기 데이터를 지워버려.
힙영역은 세 부분으로 나눌 수 있어.
1) Permanent Generation 영역
-> 생성된 객체들의 정보 주소값이 저장된 공간이야. Class loader에 의해 load되는 Class나 메소드 등에 대한 정보가 저장되는 영역이고 Reflection을 사용하여 동적으로 클래스가 로딩되는 경우 JVM에 의해 사용 돼.
※ Reflection이란 객체를 통해 클래스의 정보를 분석해 내는 프로그램 기법을 말해. 자세히 들어가면 Sprring을 공부해야하므로 다음으로 미뤄두자.
2) New/Young 영역
① Eden영역: 객체들이 최초로 생성되는 공간이야.
② Survivor 0/1: Eden에서 참조되는 객체들이 저장되는 공간이야.
3) Old 영역
New 영역에 있는 객체들이 저장되는 Eden영역이 가득 차게되면 GC가 발생해. 따라서 Eden영역에 있는 값을 Survivor 1영역에 복사하고 이외 나머지 영역의 객체를 삭제해버리지.
※ byte, short, int, long, float, double, char, boolean(이상 primitive type) 이외의 타입으로 정의된 변수는 모두 참조변수야.
이런 참조변수들은 힙영역에 값이 저장되고, 스택에는 그 주소만 저장돼!
4. PC register - PC 레지스터
Thread(쓰레드)가 생성될 때마다 생성되는 영역으로 현재 쓰레드가 실행되는 부분의 주소와 명령을 저장하고 있는 영역이야.
이것을 이용해서 쓰레드를 돌아가면서 수행할 수 있게 한다.
(쓰레드는 프로그램 실행단위! 각 쓰레드 별로 스택과 레지스터를 갖고있어.)
5. Native Method Stack
자바 외 언어로 작성된 네이티브 코드를 위한 메모리 영역이야.
보통 C/C++등의 코드를 수행하기 위한 스택
<Execution Engine>
class loader에 의해 적재된 클래스(바이트 코드)는 Execution Engine 이란 녀석이 기계어로 변환해서 명령어 단위로 실행해줘.
Heap영역 이야기할 때 잠깐 나왔는데, JVM에는 Garbage Collector(GC)라는 녀석이 있는데, 이 녀석은 heap 메모리 안에 적재된 객체 중 참조되지 않는 객체들을 탐색한 후 제거해버려. 청소부와 같은 역할인거지.
특이한 점은, GC가 수행되는 동안 GC수행 쓰레드 외의 다른 쓰레드는 모두 일시정지가 돼.
(쓰레드는 프로그램 실행단위! 각 쓰레드 별로 스택과 레지스터를 갖고있어.)
'JAVA > 이론' 카테고리의 다른 글
주석에 대하여(작성중) (0) | 2021.01.20 |
---|---|
[JAVA] 추상클래스와 인터페이스(다형성) (0) | 2021.01.05 |
[JAVA] String을 import 없이 사용할 수 있는 이유 (0) | 2021.01.05 |