Skip to content

jaeyeonling/java-jvm

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

218 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

java-jvm

CI

JVM 내부를 코드로 직접 구현하며 이해하는 교육용 프로젝트. 책이나 블로그 대신, 동작하는 코드와 719개의 테스트로 배웁니다.

javac HelloWorld.java  →  HelloWorld.class  →  이 JVM으로 실행  ✅
byte[] { 0x10, 3, 0x10, 5, 0x60, 0xAC }   →  이 JVM으로 실행  ✅

JVM을 공부할 때 "GC는 Mark-and-Sweep으로 동작한다"는 설명은 쉽게 찾을 수 있습니다. 하지만 Mark 단계에서 GC Roots를 어떻게 순회하는지, 클래스 로딩 시 <clinit>이 정확히 언제 실행되는지를 코드로 직접 확인할 수 있는 자료는 많지 않습니다.

이 프로젝트는 그 간극을 메웁니다.

무엇을 배울 수 있나

6개 챕터로 구성되어 있으며, 각 주제는 개념 → 📄 구현 코드 → 🧪 테스트 3단계로 연결됩니다.

챕터 핵심 코드 테스트
1. 클래스 파일 파싱 ClassFileParser, ConstantPool ~20개
2. 스택 기반 실행 모델 Interpreter, StackFrame ~34개
3. 바이트코드 명령어 InstructionSet, instruction/ ~243개
4. 예외 처리 ExceptionHandler, Interpreter.findHandlerPc() ~47개
5. 클래스 로딩과 초기화 ClassLoader, JVM.runClinitIfNeeded() ~78개
6. 메모리 관리와 GC MarkAndSweepGC, GenerationalHeap ~124개

각 클래스의 Javadoc에는 JVM 스펙(§ 표기) 참조가 달려 있어, 코드와 스펙을 나란히 읽을 수 있습니다.

학습 시작하기

📖 CURRICULUM.md를 따라가는 것을 권장합니다.

커리큘럼은 챕터 1부터 순서대로 읽도록 설계되어 있으며, 각 섹션마다:

  • 개념 설명과 JVM 스펙 참조
  • 구현 코드 라인 직접 링크 (ClassFileParser.java:66-79 형식)
  • 실행 가능한 테스트 파일 링크
  • 자기 점검 질문

이 갖춰져 있습니다. 처음이라면 챕터 1(클래스 파일 파싱)부터 시작하세요.

패키지 구조

src/main/java/com/jaeyeonling/jvm/
├── classfile/         클래스 파일 파싱 (ClassFileParser, ConstantPool, ClassLoader)
├── execution/         실행 엔진 (Interpreter, ExecutionEngine, InstructionSet)
│   └── instruction/   바이트코드 명령어 202개 (카테고리별 서브패키지)
├── runtime/           런타임 데이터 구조 (RuntimeClass, RuntimeMethod, ExceptionHandler)
│   └── thread/        JVM 스레드 / 스택 프레임 (JVMThread, StackFrame, OperandStack)
├── memory/            힙 / GC (Heap, GenerationalHeap, MarkAndSweepGC, ObjectHeader)
├── jdk/               JDK 네이티브 메서드 스텁 (String, Math, Integer 등)
└── cli/               커맨드라인 인터페이스 (run, bytecode, info 명령어)

30초 체험

git clone https://github.com/jaeyeonling/java-jvm.git
cd java-jvm

# HelloWorld 실행 → "Hello, JVM!" 출력
./gradlew run --args="run -cp src/test/resources/samples HelloWorld"

# .class 파일 역어셈블 — 이 프로젝트의 ClassFileParser가 직접 파싱
./gradlew run --args="bytecode src/test/resources/samples/HelloWorld.class"

역어셈블 출력 예시:

Classfile: HelloWorld.class
class HelloWorld
  superclass: java.lang.Object

  public static main([Ljava/lang/String;)V
    Code:
        0: getstatic       #7      // Field java.lang.System.out:Ljava/io/PrintStream;
        3: ldc             #15     // String "Hello, JVM!"
        5: invokevirtual   #17     // Method java.io.PrintStream.println:(Ljava/lang/String;)V
        8: return

직접 만든 Java 파일도 실행할 수 있습니다:

javac MyClass.java
./gradlew run --args="run -cp . MyClass"
./gradlew run --args="bytecode MyClass.class"

빌드 및 테스트

./gradlew build
./gradlew test   # 719개 테스트 전부 실행

요구사항: Java 21+, Gradle 8+

구현 범위와 한계

교육 목적이므로 일부 기능은 단순화하거나 생략했습니다.

항목 상태 비고
.class 파일 파싱 Java 1~21 (major 45~65)
바이트코드 실행 202개 opcode
예외 처리 (try/catch/finally) exception_table 기반
클래스 로딩 / <clinit> 부모 위임 모델 포함
Mark-and-Sweep / Reference Counting GC 교육용 단순화
invokedynamic / 람다 ⚠️ 기본 람다만 지원, 복잡한 BSM은 실패
멀티스레드 실행 단일 스레드만 지원
JIT 컴파일 인터프리터 전용 (이론은 CURRICULUM Part II-B)

참고

About

.class 파일 파싱부터 바이트코드 실행, GC까지 — JVM 인터프리터를 Java로 직접 구현하며 배우는 JVM 내부 학습 프로젝트

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Contributors

Languages