본문 바로가기
Java

자바 실행과정 쉽게 파헤치기

by Aole 2025. 1. 23.

 

자바 실행과정에 대해서 가끔 헷갈릴 때가 있다.

간단한 키워드로 모든 과정에 대해 기억할 수 있도록 하자

 

 

🔥 1. JDK (Java Development Kit)

💡 쉽게 말하면?
👉 "자바 개발에 필요한 모든 도구 세트"

📌 조금 더 설명하면?

  • 자바 프로그램을 만들고 실행하기 위한 풀 패키지.
  • 개발할 때 필요한 컴파일러(javac), 실행 환경(JRE), 개발 도구(디버거, 빌드 툴 등)가 포함돼 있어요.

📌 JDK 구성 요소
JRE (실행 환경)
컴파일러 (javac) – Java 코드를 바이트 코드로 변환
디버거, 도구들 – 개발을 편하게 해주는 프로그램들

🔹 비유: "JDK는 완전한 주방 세트! 🍽️ (냄비+프라이팬+가스레인지+음식 재료 등)"


🔥 2. JRE (Java Runtime Environment)

💡 쉽게 말하면?
👉 "자바 프로그램을 실행하는 데 필요한 환경"

📌 조금 더 설명하면?

  • 자바 프로그램을 실행할 때 필요한 필수 요소!
  • JVM + 라이브러리(클래스 파일 실행에 필요한 기본 기능) 포함.
  • 하지만 컴파일러는 없음 → 개발은 못 하고 실행만 가능!

🔹 비유: "JRE는 전자레인지 같은 거! 🍽️ (요리는 못 하지만 요리된 음식을 데워 먹을 수 있음)"


🔥 3. 자바의 컴파일 과정에서 일어나는 일

💡 쉽게 말하면?
👉 "자바 코드를 바이트 코드로 변환하는 과정"

📌 컴파일 과정 흐름
1️⃣ .java 소스 코드 작성
2️⃣ javac (컴파일러)가 코드를 .class 파일(바이트 코드)로 변환
3️⃣ 이 .class 파일을 JVM이 실행

왜 바이트 코드로 변환할까?
➡ 바이트 코드는 운영체제(OS)에 독립적이라 어디서든 실행 가능!

🔹 비유: "한글을 영어로 번역하는 것! 📝 (영어만 알면 전 세계 누구나 읽을 수 있음)"


🔥 4. 자바의 런타임 과정에서 일어나는 일

💡 쉽게 말하면?
👉 "JVM이 바이트 코드를 실행하는 과정"

📌 실행 과정 흐름
1️⃣ JVM이 바이트 코드를 읽고 실행
2️⃣ 인터프리터가 한 줄씩 읽어서 실행
3️⃣ JIT 컴파일러가 자주 실행되는 코드를 기계어로 변환해서 속도 향상

🔹 비유: "동시 통역사 🎧 (처음엔 하나씩 번역하지만, 자주 쓰이는 문장은 미리 외워서 빠르게 번역!)"


🔥 5. JVM (Java Virtual Machine)

💡 쉽게 말하면?
👉 "자바 프로그램을 실행하는 가상 컴퓨터"

📌 조금 더 설명하면?

  • 바이트 코드를 실행하는 핵심 엔진!
  • OS와 상관없이 동일한 바이트 코드를 실행할 수 있도록 해줌.

왜 필요할까?
운영체제(OS) 독립성을 유지하기 위해!

🔹 비유: "게임 콘솔 🎮 (닌텐도 스위치 게임 카트리지를 PC에서 실행할 수는 없지만, 닌텐도 스위치에서 실행할 수 있는 것처럼!)"


🔥 6. ClassLoader

💡 쉽게 말하면?
👉 "클래스 파일을 JVM에 불러오는 역할"

📌 조금 더 설명하면?

  • .class 파일을 JVM이 실행할 수 있도록 메모리에 로드하는 역할.
  • 필요할 때만 메모리에 올려서 사용 가능하도록 해줌.

🔹 비유: "도서관 사서 📚 (책이 필요할 때만 가져오고, 안 쓰면 다시 제자리에 두는 것!)"


🔥 7. Runtime Data Area

💡 쉽게 말하면?
👉 "JVM이 실행 중에 사용하는 메모리 공간"

📌 구성 요소
Heap – 객체 저장
Stack – 메서드 호출 정보 저장
Method Area – 클래스 정보 저장

🔹 비유: "작업 공간! 🏢 (Heap=서류 창고, Stack=작업 중인 책상, Method Area=매뉴얼 보관함)"


🔥 8. Heap

💡 쉽게 말하면?
👉 "객체(인스턴스)가 저장되는 공간"

📌 조금 더 설명하면?

  • new 키워드로 만든 객체들이 저장되는 영역.
  • 가비지 컬렉터(GC)가 필요 없어진 객체를 정리함.

🔹 비유: "창고 📦 (필요한 물건을 꺼내 쓰고, 필요 없으면 버림)"


🔥 9. Stack

💡 쉽게 말하면?
👉 "메서드 실행 정보가 저장되는 공간"

📌 조금 더 설명하면?

  • 메서드가 호출될 때마다 스택 프레임이 생성됨.
  • 메서드가 끝나면 스택에서 제거됨.

🔹 비유: "쌓이는 접시 🍽️ (맨 위부터 차례로 쌓이고, 다 쓰면 하나씩 제거됨)"


🔥 10. PC Register

💡 쉽게 말하면?
👉 "현재 실행 중인 명령어의 위치를 저장하는 공간"

📌 조금 더 설명하면?

  • JVM이 현재 실행 중인 바이트 코드의 주소(위치)를 저장하는 레지스터.

🔹 비유: "책갈피 📖 (지금 어디까지 읽었는지 표시해두는 것!)"


🔥 11. Native Method Area

💡 쉽게 말하면?
👉 "C/C++ 같은 네이티브 코드를 실행하는 공간"

📌 조금 더 설명하면?

  • 자바가 아닌 운영체제(C/C++)의 네이티브 코드를 실행할 때 사용됨.
  • JNI(Java Native Interface)로 연결됨.

🔹 비유: "외국어 통역 🎙️ (자바가 모르는 언어를 번역해서 실행하는 것!)"


🔥 12. Execution Engine

💡 쉽게 말하면?
👉 "JVM이 바이트 코드를 실행하는 엔진"

📌 조금 더 설명하면?

  • 바이트 코드를 해석해서 실행하는 역할.
  • 인터프리터와 JIT 컴파일러가 포함됨.

🔹 비유: "자동차 엔진 🚗 (연료(바이트 코드)를 넣으면 실제로 움직이게 만드는 역할)"


🔥 13. JIT (Just-In-Time) 컴파일러

💡 쉽게 말하면?
👉 "자주 실행되는 코드를 미리 기계어로 변환해서 빠르게 실행하도록 하는 컴파일러"

📌 조금 더 설명하면?

  • 인터프리터 방식으로 실행되는 코드를 캐싱해서 최적화함.
  • 반복 실행되는 코드를 빠르게 실행할 수 있도록 최적화함.

🔹 비유: "단골 메뉴 🍕 (매번 조리하는 게 아니라 미리 만들어 두고 빠르게 제공!)"


🔥 14. Garbage Collector

💡 쉽게 말하면?
👉 "사용하지 않는 객체를 자동으로 정리하는 기능"

📌 조금 더 설명하면?

  • Heap 메모리에 쌓인 필요 없는 객체를 자동으로 제거함.
  • 메모리를 효율적으로 관리하는 역할.

🔹 비유: "청소부 🧹 (더 이상 사용하지 않는 물건을 자동으로 치워줌!)"


 

 

Native Method Stack, Execution Engine, JIT에 대해 좀 더 알아보자!

 

1. Native Method Stack (네이티브 메서드 스택)

💡 쉽게 말하면?
👉 "자바가 아닌 C나 C++ 같은 다른 언어로 만든 함수를 실행하는 공간이에요."

📌 조금 더 설명하면?

  • 자바는 JVM 위에서 동작하지만, 때때로 운영체제에 직접 접근해야 할 때가 있어요.
  • 예를 들어, 하드웨어와 직접 연결된 시스템 함수(파일 시스템, 네트워크 등)를 사용할 때 C/C++ 코드가 필요할 수 있어요.
  • 이런 **네이티브 코드(C/C++)를 실행하는 공간이 바로 ‘네이티브 메서드 스택’**이에요.
  • 이때 JNI(Java Native Interface) 라는 기술을 사용해서 네이티브 코드와 연결해요.

📌 예제

public class NativeExample {
    static {
        System.loadLibrary("nativeLib"); // 네이티브 라이브러리 로드
    }

    public native void nativeMethod(); // 네이티브 메서드 선언

    public static void main(String[] args) {
        new NativeExample().nativeMethod(); // 네이티브 메서드 호출
    }
}

🔹 여기서 nativeMethod()는 자바 코드가 아니라 C/C++에서 구현된 코드예요.


2. Execution Engine (실행 엔진)

💡 쉽게 말하면?
👉 "JVM이 자바 코드를 실제로 실행하는 엔진이에요."

📌 조금 더 설명하면?

  • 우리가 작성한 **자바 코드(.java)**는 **바이트 코드(.class)**로 변환된 후 JVM이 실행해요.
  • 이 실행을 담당하는 게 바로 **Execution Engine(실행 엔진)**이에요.
  • 실행 엔진은 바이트 코드를 기계어(컴퓨터가 이해하는 언어)로 변환해서 실행해요.
  • 실행 방식에는 인터프리터 방식과 JIT 컴파일러 방식이 있어요.

3. JIT (Just-In-Time) 컴파일러

💡 쉽게 말하면?
👉 "인터프리터 방식으로 실행하던 코드를 빠르게 실행하려고 미리 기계어로 변환해서 저장하는 기능이에요!"

📌 조금 더 설명하면?

  • 자바는 기본적으로 한 줄 한 줄 코드를 해석하며 실행하는 인터프리터 방식을 사용해요.
  • 하지만 매번 해석하면 속도가 느려지니까, 실행할 때마다 자주 사용되는 코드를 **한 번에 변환해서 캐싱(저장)**하는 기술이 JIT 컴파일러예요.
  • 이렇게 변환된 코드는 다시 변환하지 않고 바로 실행되므로 성능이 훨씬 빨라져요! 🚀

📌 예제

  1. 처음에는 JVM이 바이트 코드를 한 줄씩 해석해서 실행해요. (인터프리터)
  2. 그런데 어떤 코드가 계속 반복해서 실행되면, JIT 컴파일러가 그 코드를 네이티브 코드로 변환해서 저장해요.
  3. 이후에는 해석 없이 바로 실행할 수 있어 실행 속도가 빨라져요.

📌 세 가지 개념의 관계

1️⃣ **Execution Engine(실행 엔진)**이 자바 코드를 실행한다.
2️⃣ 실행할 때 네이티브 코드가 필요하면 Native Method Stack을 사용해서 C/C++ 코드 실행.
3️⃣ 실행 속도를 높이기 위해 JIT 컴파일러가 자주 실행되는 코드를 네이티브 코드로 변환하여 캐싱.