Class Loader 글 이후로 이어서 포스팅 해보겠다.
JVM에는 Class Loader, Runtime Data Areas, Execution Engine 이렇게 3개로 구성되어 있다.
Class Loader에서 class 파일들을 동적으로 로드하고, Runtime Data Areas에 올려준다고 했었다. 이제 Runtime Data Areas를 알아보자
처음 시리즈부터 다시 보고 싶다면?
JDK, JRE, JVM부터 다시 보기
JVM의 메모리 영역으로 자바 애플리케이션을 실행할 때 사용되는 데이터들을 적재하는 영역이다.
런타임 데이터 영역은 크게 Method Area, Heap Area, Stack Area, PC Register, Native Method Stack으로 나눌 수 있다.
Method Area와 Heap 영역은 Thread들이 서로 공유하는 영역이기 때문에 동시성 문제를 고려해야 한다.
JVM이 시작될 때 생성되는 공간으로 바이트 코드(.class)를 처음 메모리 공간에 올릴 때 초기화되는 대상을 저장하기 위한 메모리 공간이다.
JVM이 동작하고 클래스가 로드될 때 적재돼서 프로그램이 종료될 때까지 저장된다.
Method Area 영역에 포함되지만 독자적 중요성을 띈다.
힙 영역은 메서드 영역과 함께 모든 쓰레드가 공유하며, JVM이 관리하는 프로그램 상에서 데이터를 저장하기 위해 런타임 시 동적으로 할당하여 사용하는 영역이다.
즉, new 연산자로 생성되는 클래스와 인스턴스 변수, 배열 타입 등 Reference Type이 저장되는 곳이다.
Method Area 영역에 저장된 클래스만이 생성이 되어 적재된다.
int, long, boolean 등 기본 자료형을 생성할 때 저장하는 공간으로, 임시적으로 사용되는 변수나 정보들이 저장되는 영역이다.
쓰레드가 시작될 때 생성되며, 현재 수행중인 JVM 명령어 주소를 저장하는 공간이다.
JVM 명령어 주소는 쓰레드가 어떤 부분을 무슨 명령으로 실행해야할 지에 대한 기록을 가지고 있다.
자바 코드가 컴파일되어 생성되는 바이트 코드가 아닌 실제 실행할 수 있는 기계어로 작성된 프로그램을 실행시키는 영역이다.
그림에서 보이는 metaspace가 method 영역이다.
method 영역이 Java 8 이상에서는 PermGen이 Metaspace로 대체되었다.
전체 실행 코드는 다음과 같다.
public class MainCustomer extends Customer {
String hobby;
public MainCustomer() {
}
public MainCustomer(String name, int age, String address, String hobby) {
super(name, age, address);
this.hobby= hobby;
}
public String customerInfo() {
return super.customerInfo()+" 취미:"+hobby;
}
}
public class Customer {
String name;
int age;
String address;
public Customer( ) {
this("ssafy", 12, "서울");
}
public Customer(String name, int age, String address){
this.name = name;
this.age = age;
this.address = address;
}
public boolean equals(Object o) {
return this == o;
}
String customerInfo() {
return "이름:"+name+" 나이:"+age+" 주소:"+address;
}
}
public class InheritacneTest {
public static void main(String[] args) {
MainCustomer mcust = new MainCustomer("ssafy", 12, "서울", "코딩");
System.out.println(mcust.customerInfo());
}
}
이렇게 3개의 자바 파일이 있고, MainCustomer는 customer를 상속받고 있다. 이 코드에서 main 문을 실행할 때 전체적으로 runtime data 영역에서 어떻게 동작하는지 보자.
MainCustomer mcust=new MainCustomer("ssafy", 12, "서울", "코딩");
System.out.println(mcust.customerInfo());
이 코드를 실행할 때, 그림처럼 동작이 된다.
자세히 살펴보면,
이렇게 Runtime Data Areas에 대해서도 알아보았다.
다음에는 Execution Engine에 대해 알아보겠다.