JAVA/이론

[JAVA] JVM (자바가상머신)

Sunwoo_bang 2021. 1. 4. 23:15

 

JVM이란 JAVA Virtual Machine을 이르는 말이야.
JVM은 코드를 실행하고 해당 코드에 대해 런타임 환경을 제공하는 소프트웨어 프로그램에 대한 사양이라고 하는데
그냥 쉽게 말해서 자바 프로그램을 실행하는 방법이라고 보면 돼.

 

전체적인 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수행 쓰레드 외의 다른 쓰레드는 모두 일시정지가 돼.
(쓰레드는 프로그램 실행단위! 각 쓰레드 별로 스택과 레지스터를 갖고있어.)