Search

GC를 이해하기 위해 알아야 되는 OS 지식

JVM을 실행할 수 있는 환경이라면, 어디든지 Jar파일을 동작 시킬수 있습니다.
JVM은 바이트코드를 해석하거나 실행할 수 있는 실행파일 이기 때문 입니다.

프로세스로 실행되는 건 jar 파일인가 java 실행 파일인가?

myapp.jar = 특수한 형태의 ZIP 압축 파일 ├── META-INF/ │ └── MANIFEST.MF (메타정보) ├── com/example/ │ ├── Main.class (컴파일된 바이트코드) │ └── Service.class └── application.properties
Plain Text
복사
# 이렇게 실행하면 java -jar myapp.jar # 실제로는 이런 일이 벌어집니다 /usr/bin/java ← 이게 실행 파일이고 프로세스가 됨
Plain Text
복사

/bin/java 실행 후 우리가 작성한 Main.class까지 접근하는 방법

// 1. 진입점: java 명령어 실행 JNIEXPORT int main(int argc, char **argv) { return JLI_Launch(argc, argv, ...); } // 2. JLI_Launch 내부에서 플랫폼별 처리 후 int CallJavaMainInNewThread(jlong stack_size, void* args) { // 새로운 스레드 생성 (필요 시) if (pthread_create(&tid, &attr, ThreadJavaMain, args) == 0) { // 성공: 새 스레드에서 JavaMain 실행 pthread_join(tid, &res); } else { // 실패: 현재 스레드에서 JavaMain 실행 rslt = JavaMain(args); } } // 3. 실제 Java 실행 로직 int JavaMain(void* _args) { // ① JVM 초기화 if (!InitializeJVM(&vm, &env, &ifn)) { // 실패 처리 } // InitializeJVM 내부: result = JNI_CreateJavaVM(&vm, (void**)&env, &args);// hotspot/share/prims/jni.cpp jint JNI_CreateJavaVM(JavaVM **vm, void **penv, void *args) { result = Threads::create_vm( (JavaVMInitArgs*) args, &can_try_again ); }// Threads::create_vm 내부에서 JavaThread* main_thread = JavaThread::create_system_thread_object(...); // ② Main 클래스 로딩 mainClass = LoadMainClass(env, mode, what); // 예: "com.example.Application" 클래스 찾기 // ③ main 메서드 ID 가져오기 mainID = (*env)->GetStaticMethodID(env, mainClass, "main", "([Ljava/lang/String;)V"); // ④ main 메서드 호출 (*env)->CallStaticVoidMethod(env, mainClass, mainID, mainArgs); // 또는 // ret = invokeStaticMainWithoutArgs(env, mainClass); return 0; }
C++
복사

Kernel Thread : OS Thread : JVM Thread : java.lang.Thread 관계 부연설명

1:1:1:1 관계 부연설명

VM이 바이트코드를 실행하는 두 가지 흐름

public class Main { public static void main (String[] args) { superAmazingPopularMethod(); } public static void superAmazingPopularMethod) { int a = 10; int b = a + 7; // .... }
Java
복사
public static void main(java.lang. String[]); Code: 0: invokestatic 3: return #7 public static void superAmazingPopularMethod); Code: 0: bipush 2: istore_0 3: iload_0 4: bipush 6: iadd 7: istore_1 8: return
Java
복사
1. Interpreter (인터프리터)
바이트코드를 한 줄씩 해석해서 실행
바이트코드를 한 줄씩 읽으면서 각 명령어에 정의된 동작을 내부 코드로 실행하는 방식
java 명령으로 프로그램을 실행하면 기본적으로 인터프리터가 바이트코드를 해석하며 실행
2. JIT Compiler (Just-In-Time 컴파일러)
자주 사용되는 코드를 기계어로 컴파일해서 성능 최적화
바이트코드 중 자주 호출되는 메서드나 반복문(loop) 블록을 감지
해당 코드를 최적화된 네이티브 기계어로 컴파일하여 Code Cache에 저장
이후 같은 코드 실행 시 컴파일된 기계어를 직접 호출하여 빠르게 실행