
주로 3가지 동작을 담당한다.
클래스 로더가 .class 파일을 읽고 바이너리 데이터를 생성하여 메서드 영역에 저장한다. 메서드 영역에는 다음과 같은 정보들이 .class 파일마다 저장된다.
.class 파일이 클래스인지 / 인터페이스인지 / enum인지.class 파일을 로드한 후, JVM은 이 파일을 표현하기 위해 힙 메모리에 Class 타입의 객체를 생성한다.
이 객체는 java.lang 패키지에 미리 정의되어 있는 Class 타입이다.
이 Class 객체는 프로그래머가 클래스 수준의 정보(예: 클래스 이름, 부모 이름, 메서드와 변수 정보 등)를 얻는 데 사용할 수 있다.
이 객체의 참조를 얻기 위해서는 Object 클래스의 getClass() 메서드를 사용할 수 있다.
Example:
// A Java program to demonstrate working
// of a Class type object created by JVM
// to represent .class file in memory
import java.lang.reflect.Field;
import java.lang.reflect.Method;
// Java code to demonstrate use
// of Class object created by JVM
public class Geeks
{
public static void main(String[] args)
{
Student s1 = new Student();
// Getting hold of Class
// object created by JVM.
Class c1 = s1.getClass();
// Printing type of object using c1.
System.out.println(c1.getName());
// getting all methods in an array
Method m[] = c1.getDeclaredMethods();
for (Method method : m)
System.out.println(method.getName());
// getting all fields in an array
Field f[] = c1.getDeclaredFields();
for (Field field : f)
System.out.println(field.getName());
}
}
// A sample class whose information
// is fetched above using its Class object.
class Student {
private String name;
private int roll_No;
public String getName() { return name; }
public void setName(String name) { this.name = name; }
public int getRoll_no() { return roll_No; }
public void setRoll_no(int roll_no)
{
this.roll_No = roll_no;
}
}
Output
Student
getName
setName
getRoll_no
setRoll_no
name
roll_No
참고로, 로드된 모든 .class 파일에, Class 객체는 하나씩만 생성된다.
Student s2 = new Student();
// c2 will point to same object where
// c1 is pointing
Class c2 = s2.getClass();
System.out.println(c1==c2); // true
검증(verification), 준비(preparation), 그리고 (선택적으로) 해석(resolution)을 수행한다.
.class 파일의 정확성을 보장한다. (올바르게 형식화되어 있는지, 유효한 컴파일러에 의해 생성되었는지)이 단계에서는 모든 static 변수에 코드와 static 블록(있을 경우)에 정의된 값이 할당된다.
이는 클래스 내에서는 위에서 아래로, 클래스 계층 구조에서는 부모에서 자식 순서로 실행된다.
Java 런타임 데이터 영역(runtime data area)의 일부는 JVM이 생성하고, 일부는 프로그램에서 사용되는 쓰레드가 생성한다.
JVM 메모리 구조에는 다음 영역들이 포함된다:

new 키워드를 사용하면 객체는 힙에 할당되고, 그 객체의 참조값은 스택에 저장된다.Scanner sc = new Scanner(System.in)
여기서 Scanner 객체는 힙에, 참조인 sc는 스택에 저장된다.
실행 엔진은 .class(바이트코드)를 실행한다. 바이트코드를 한 줄씩 읽고, 다양한 메모리 영역에 있는 데이터와 정보를 사용하여 명령어들을 실행한다.
실행 엔진은 세 부분으로 나뉜다.
Interpreter: 바이트코드를 한 줄씩 해석해서 실행한다. 단점은, 한 메서드가 여러 번 호출되면 매번 해석을 해야 한다는 것이다.
Just-In-Time Compiler(JIT): 인터프리터의 효율을 높이기 위해 사용된다. 자주 실행되는 코드 블록을 바이트코드를 컴파일하여 네이티브 코드(특정 하드웨어나 운영 체제에서 직접 실행될 수 있는 코드)로 변환한다. 인터프리터가 반복된 메서드 호출을 마주하면 JIT가 해당 부분에 대한 네이티브 코드를 제공하여 중복 해석을 방지한다.
Garbage Collector: 참조되지 않은 객체들을 제거한다.
Native Method Library와 상호작용하여 실행에 필요한 네이티브 라이브러리(C, C++)를 제공하는 인터페이스
JVM이 특정 하드웨어에 종속적인 C/C++ 라이브러리를 호출하거나 해당 라이브러리에 호출받을 수 있도록 해준다.
네이티브 메서드들을 실행하는 데 필요한 네이티브 라이브러리들의 모음