

.java 컴파일을 하려할 때, javac이라는 Compiler가 Byte Code인 .class로 컴파일함
이 .class 파일을 처리하는 곳이 JVM이며, Class loader, Runtime Data Areas, Execution Engine을 포함함
runtime에 순환하며 일어나는 과정
이 때, runtime data area에서 자바 어플리케이션에 사용되는 데이터를 적재함.
이는 Method Area, Heap Area, Stack Area, PC Register, Native Method Stack으로 나뉨

모든 스레드가 공유하는 메모리 영역
클래스, 인터페이스, 메소드, 속성, static 변수 등의 바이트 코드를 보관함
런타임 중에 변경될 수 없다는 특징이 있으며 고정된 공간을 차지함
모든 스레드가 공유하는 메모리 영역
new 키워드로 생성된 객체와 배열이 생성됨
메모리의 낮은 주소에서 높은 주소의 방향으로 데이터가 할당됨
method area에 로드된 클래스로만 객체 생성이 가능하며, garbage collector의 주요 대상임
메소드 호출될 때 메소드의 스택 프레임이 생성됨
스택 프레임에서 메소드 안에 사용된 원시 타입의 매개변수, 지역변수 데이터를 저장함
동적으로 생성된 객체일 경우, 힙 메모리 영역의 주소값을 저장함
메모리의 높은 주소에서 낮은 주소 방향으로 데이터가 할당됨
메소드 수행이 끝난 경우 프레임 별로 삭제됨
쓰레드가 시작될 때 생성되며, 쓰레드마다 하나씩 존재함
현재 어떤 명령어를 실행해는 지를 기록하며, 수행중인 명령어의 주소를 가짐
자바 외 언어로 작성된 코드를 위한 메모리 영역


소스 코드 (고급 언어) 전체를 기계어로 번역후 실행함
예시 : C, C++
소스코드를 중간언어로 번역한 다음, 한줄 씩 대응하는 기계어 코드를 실행함
예시 : 파이썬, 루비 등
정적 컴파일 + 인터프리터의 하이브리드 형식으로, 동적 번역을 사용함
실행할 때, 인터프리터 방식으로 기계어 코드를 생성함과 동시에 캐싱함
예시 : Java의 JVM
public class Main {
static int num = 1;
public static void main(String[] args) {
int a = 100;
int b = 200;
int c = a + b;
Test t = new Test();
c = c + t.num;
}
}
class Test {
int num = 90;
}
위의 코드를 javac으로 컴파일
javac Main.java
그러면 Main.class가 생기는데 이 파일 보기
javap -c Main.class
Compiled from "Main.java"
public class Main {
static int num;
public Main();
Code:
0: aload_0
1: invokespecial #1 // Method java/lang/Object."<init>":()V
4: return
public static void main(java.lang.String[]);
Code:
0: bipush 100
2: istore_1
3: sipush 200
6: istore_2
7: iload_1
8: iload_2
9: iadd
10: istore_3
11: new #7 // class Test
14: dup
15: invokespecial #9 // Method Test."<init>":()V
18: astore 4
20: iload_3
21: aload 4
23: getfield #10 // Field Test.num:I
26: iadd
27: istore_3
28: return
static {};
Code:
0: iconst_1
1: putstatic #14 // Field num:I
4: return
}
https://steady-coding.tistory.com/305
https://velog.io/@rik963/JAVA-JVM-구조-및-메모리-영역-Class-Heap-Stack-Area
https://www.devkuma.com/docs/jvm/memory-structure/