Post

๐Ÿ“‘ JAVA 02 - JVM ClassLoader์™€ ์‹คํ–‰ ๊ตฌ์กฐ

๐Ÿ“‘ JAVA 02 - JVM ClassLoader์™€ ์‹คํ–‰ ๊ตฌ์กฐ

์ถ”์ฒœ ํŒŒ์ผ๋ช…

2026-05-14-jvm-classloader-runtime-structure.md


title: โ€œJVM ClassLoader์™€ ์‹คํ–‰ ๊ตฌ์กฐ - ์™œ Java๋Š” ๋™์ ์œผ๋กœ ํด๋ž˜์Šค๋ฅผ ๋กœ๋”ฉํ•˜๋Š”๊ฐ€?โ€

date: 2026-05-14
categories: [To-Be-Senior]
tags: [Java, JVM, ClassLoader, Reflection, Runtime, Backend]

JVM ClassLoader์™€ ์‹คํ–‰ ๊ตฌ์กฐ

ํ•™์Šต ๋ชฉํ‘œ

์ด๋ฒˆ ์ฃผ์ œ์˜ ํ•ต์‹ฌ์€ ๋‹จ์ˆœํžˆ:

โ€œClassLoader๋Š” ํด๋ž˜์Šค๋ฅผ ์ฝ๋Š” ๊ฐ์ฒดโ€

์ˆ˜์ค€์ด ์•„๋‹ˆ๋‹ค.

์‹ค๋ฌด์—์„œ๋Š” ๋‹ค์Œ์„ ์ดํ•ดํ•ด์•ผ ํ•œ๋‹ค.

  • JVM์€ ์™œ ClassLoader ๊ตฌ์กฐ๋ฅผ ๋งŒ๋“ค์—ˆ๋Š”๊ฐ€?

  • ์™œ ๋ถ€๋ชจ ์œ„์ž„ ๋ชจ๋ธ์ด ํ•„์š”ํ•œ๊ฐ€?

  • Runtime Dynamic Loading์€ ์–ด๋–ค ์žฅ์ ์„ ๊ฐ€์ง€๋Š”๊ฐ€?

  • Reflection์€ ์™œ ๋А๋ฆฌ๋‹ค๊ณ  ํ•˜๋Š”๊ฐ€?

  • Spring์€ ์–ด๋–ป๊ฒŒ ๋™์ ์œผ๋กœ Bean์„ ์ƒ์„ฑํ•˜๋Š”๊ฐ€?

  • ์šด์˜ ํ™˜๊ฒฝ์—์„œ ClassLoader๋Š” ์™œ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋ฅผ ์œ ๋ฐœํ•˜๋Š”๊ฐ€?

์ฆ‰:

โ€œJava ๋Ÿฐํƒ€์ž„ ์‹œ์Šคํ…œ์˜ ํ•ต์‹ฌ ๋ฉ”์ปค๋‹ˆ์ฆ˜โ€

์„ ์ดํ•ดํ•˜๋Š” ๊ฒƒ์ด ๋ชฉํ‘œ๋‹ค.


JVM ์‹คํ–‰ ๊ตฌ์กฐ

flowchart TD

    A[.java Source] --> B[javac Compile]
    B --> C[.class Bytecode]
    C --> D[JVM Start]
    D --> E[ClassLoader]
    E --> F[Runtime Data Area]
    F --> G[Execution Engine]

Java๋Š”:

์‹คํ–‰ ์‹œ์ (Runtime)์— ํด๋ž˜์Šค ๋กœ๋”ฉ์ด ์ด๋ฃจ์–ด์ง„๋‹ค.

์ด๊ฒŒ C/C++์™€ ๊ฐ€์žฅ ํฐ ์ฐจ์ด ์ค‘ ํ•˜๋‚˜๋‹ค.


ClassLoader๋ž€ ๋ฌด์—‡์ธ๊ฐ€?

ClassLoader๋Š”:

.class Bytecode๋ฅผ JVM ๋ฉ”๋ชจ๋ฆฌ์— ์ ์žฌํ•˜๋Š” ์—ญํ• 

์„ ์ˆ˜ํ–‰ํ•œ๋‹ค.

Java์˜ ๋ชจ๋“  ํด๋ž˜์Šค๋Š” ๋ฐ˜๋“œ์‹œ ClassLoader๋ฅผ ํ†ตํ•ด ๋กœ๋”ฉ๋œ๋‹ค.


JVM ClassLoader ๊ตฌ์กฐ

flowchart TD

    A[Bootstrap ClassLoader]
    B[Platform ClassLoader]
    C[Application ClassLoader]

    A --> B
    B --> C

Bootstrap ClassLoader

์ตœ์ƒ์œ„ ๋กœ๋”.

ํ•ต์‹ฌ Java ํด๋ž˜์Šค ๋กœ๋”ฉ ๋‹ด๋‹น:

  • java.lang

  • java.util

  • java.io

์˜ˆ:

1
System.out.println(String.class.getClassLoader());

๊ฒฐ๊ณผ:

1
null

Bootstrap Loader๋Š” Native(C++) ์˜์—ญ์—์„œ ๋™์ž‘ํ•˜๊ธฐ ๋•Œ๋ฌธ์— null๋กœ ํ‘œํ˜„๋œ๋‹ค.


Application ClassLoader

๊ฐœ๋ฐœ์ž๊ฐ€ ์ž‘์„ฑํ•œ ํด๋ž˜์Šค๋ฅผ ๋กœ๋”ฉํ•œ๋‹ค.

1
2
3
4
5
6
public class Main {

    public static void main(String[] args) {
        System.out.println(Main.class.getClassLoader());
    }
}

์ถœ๋ ฅ:

1
jdk.internal.loader.ClassLoaders$AppClassLoader

๋ถ€๋ชจ ์œ„์ž„ ๋ชจ๋ธ (Parent Delegation Model)

ClassLoader์˜ ํ•ต์‹ฌ ๊ตฌ์กฐ๋‹ค.

flowchart TD

    A[ํด๋ž˜์Šค ๋กœ๋”ฉ ์š”์ฒญ]
        --> B[๋ถ€๋ชจ ClassLoader ์œ„์ž„]

    B --> C{๋ถ€๋ชจ๊ฐ€ ํด๋ž˜์Šค ๋ฐœ๊ฒฌ?}

    C -->|YES| D[๋ถ€๋ชจ๊ฐ€ ๋กœ๋”ฉ]
    C -->|NO| E[ํ˜„์žฌ Loader๊ฐ€ ๋กœ๋”ฉ]

์™œ ์ด๋ ‡๊ฒŒ ์„ค๊ณ„ํ–ˆ๋Š”๊ฐ€?

1. ๋ณด์•ˆ

๋งŒ์•ฝ ๋ถ€๋ชจ ์œ„์ž„์ด ์—†๋‹ค๋ฉด:

1
2
3
4
package java.lang;

public class String {
}

๊ฐ™์€ ์•…์„ฑ ํด๋ž˜์Šค๋ฅผ ๋งŒ๋“ค ์ˆ˜ ์žˆ๋‹ค.

์ฆ‰:

Java ํ•ต์‹ฌ ํด๋ž˜์Šค๋ฅผ ์œ„์กฐ ๊ฐ€๋Šฅ

ํ•ด์ง„๋‹ค.

๋ถ€๋ชจ ์œ„์ž„ ๋ชจ๋ธ์€ ํ•ญ์ƒ Bootstrap Loader๋ฅผ ์šฐ์„  ์‚ฌ์šฉํ•˜์—ฌ ์ด๋ฅผ ๋ง‰๋Š”๋‹ค.


2. ํด๋ž˜์Šค ์ค‘๋ณต ๋ฐฉ์ง€

Java์—์„œ ํด๋ž˜์Šค๋Š”:

1
ํด๋ž˜์Šค ์ด๋ฆ„ + ClassLoader

์กฐํ•ฉ์œผ๋กœ ์‹๋ณ„๋œ๋‹ค.

์ฆ‰:

๊ฐ™์€ ํด๋ž˜์Šค๋ผ๋„ ClassLoader๊ฐ€ ๋‹ค๋ฅด๋ฉด ๋‹ค๋ฅธ ํƒ€์ž…์ด๋‹ค.


Loading โ†’ Linking โ†’ Initialization

ํด๋ž˜์Šค ๋กœ๋”ฉ์€ ๋‹จ์ˆœ ํŒŒ์ผ ์ฝ๊ธฐ๊ฐ€ ์•„๋‹ˆ๋‹ค.

3๋‹จ๊ณ„๋ฅผ ๊ฑฐ์นœ๋‹ค.

flowchart LR

    A[Loading]
        --> B[Linking]
        --> C[Initialization]

1. Loading

.class ํŒŒ์ผ์„ ์ฝ๋Š”๋‹ค.


2. Linking

๋ฉ”๋ชจ๋ฆฌ ์—ฐ๊ฒฐ ๋ฐ ๊ฒ€์ฆ ์ˆ˜ํ–‰.

์„ธ๋ถ€ ๋‹จ๊ณ„:

  • Verify

  • Prepare

  • Resolve

์—ฌ๊ธฐ์„œ Bytecode ๊ฒ€์ฆ์ด ๋ฐœ์ƒํ•œ๋‹ค.


3. Initialization

์ •์  ๋ณ€์ˆ˜ ์ดˆ๊ธฐํ™” ์ˆ˜ํ–‰.

1
2
3
static {
    System.out.println("init");
}

Runtime Dynamic Loading

Java์˜ ํ•ต์‹ฌ ํŠน์ง• ์ค‘ ํ•˜๋‚˜๋‹ค.

1
2
Class<?> clazz =
    Class.forName("com.mysql.jdbc.Driver");

์‹คํ–‰ ์‹œ์ ์— ํด๋ž˜์Šค๋ฅผ ๋™์ ์œผ๋กœ ๋กœ๋”ฉํ•œ๋‹ค.


์™œ ์ค‘์š”ํ•œ๊ฐ€?

์ด ๊ตฌ์กฐ ๋•๋ถ„์— Java๋Š”:

  • Spring

  • JDBC

  • Tomcat

  • JPA Proxy

  • AOP Proxy

๊ฐ™์€ ๊ฐ•๋ ฅํ•œ ๋Ÿฐํƒ€์ž„ ํ™•์žฅ์„ฑ์„ ๊ฐ€์ง„๋‹ค.

์ฆ‰:

Java ์ƒํƒœ๊ณ„ ์œ ์—ฐ์„ฑ์˜ ํ•ต์‹ฌ

์ด๋‹ค.


Reflection๊ณผ ์—ฐ๊ฒฐ

Reflection์€:

๋Ÿฐํƒ€์ž„์— ํด๋ž˜์Šค ์ •๋ณด๋ฅผ ์กฐ์ž‘ํ•˜๋Š” ๊ธฐ์ˆ 

์ด๋‹ค.

1
2
3
4
Class<?> clazz = User.class;

Method[] methods =
    clazz.getDeclaredMethods();

Spring์€ ์™œ Reflection์„ ์‚ฌ์šฉํ•˜๋Š”๊ฐ€?

Spring ๋‚ด๋ถ€๋Š” Reflection ๊ธฐ๋ฐ˜์ด๋‹ค.

๋Œ€ํ‘œ ์‚ฌ๋ก€:

  • Bean ์ƒ์„ฑ

  • DI ์ฃผ์ž…

  • AOP Proxy

  • Annotation ๋ถ„์„

์ฆ‰:

Spring ๋‚ด๋ถ€๋Š” Runtime Dynamic Loading + Reflection ๊ธฐ๋ฐ˜

์ด๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.


Reflection์€ ์™œ ๋А๋ฆฐ๊ฐ€?

์ผ๋ฐ˜ ํ˜ธ์ถœ:

1
user.getName();

Reflection ํ˜ธ์ถœ:

1
method.invoke(user);

Reflection์€:

  • ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ํƒ์ƒ‰

  • ์ ‘๊ทผ ์ œ์–ด ๊ฒ€์‚ฌ

  • ๋™์  ํ˜ธ์ถœ

๊ณผ์ •์ด ์ถ”๊ฐ€๋œ๋‹ค.


ํ•˜์ง€๋งŒ ์‹ค๋ฌด์—์„œ ์ง„์งœ ๋ณ‘๋ชฉ์ธ๊ฐ€?

๋Œ€๋ถ€๋ถ„์€ ์•„๋‹ˆ๋‹ค.

์‹ค์ œ ๋ณ‘๋ชฉ์€ ๋ณดํ†ต:

  • DB

  • Network

  • External API

์—์„œ ๋ฐœ์ƒํ•œ๋‹ค.

Reflection์€ ๋ณดํ†ต startup ๊ตฌ๊ฐ„์—์„œ ๋งŽ์ด ์‚ฌ์šฉ๋œ๋‹ค.


Spring Boot Auto Configuration

flowchart TD

    A[Spring Boot Start]
        --> B[Classpath Scan]

    B --> C{ํŠน์ • ํด๋ž˜์Šค ์กด์žฌ?}

    C -->|YES| D[Auto Configuration]
    C -->|NO| E[Skip]

๋Œ€ํ‘œ ์‚ฌ๋ก€:

  • JDBC Driver

  • Redis

  • Kafka

์ž๋™ ์—ฐ๊ฒฐ.


Tomcat๊ณผ ClassLoader

Tomcat์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๋ณ„ ๋…๋ฆฝ ClassLoader๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

flowchart TD

    A[Tomcat]

    A --> B[WebApp ClassLoader A]
    A --> C[WebApp ClassLoader B]

์™œ?

  • ํด๋ž˜์Šค ์ถฉ๋Œ ๋ฐฉ์ง€

  • ๋…๋ฆฝ ๋ฐฐํฌ

  • Hot Reload ์ง€์›


์šด์˜ ํ™˜๊ฒฝ ํ•ต์‹ฌ ๋ฌธ์ œ

ClassLoader Memory Leak

์‹ค์ œ ์šด์˜์—์„œ ๋งค์šฐ ์œ ๋ช…ํ•œ ์žฅ์•  ์›์ธ์ด๋‹ค.

ํŠนํžˆ:

  • Tomcat

  • DevTools

  • Hot Reload

ํ™˜๊ฒฝ์—์„œ ์ž์ฃผ ๋ฐœ์ƒํ•œ๋‹ค.


์™œ ๋ฐœ์ƒํ•˜๋Š”๊ฐ€?

ClassLoader๊ฐ€ GC๋˜์ง€ ๋ชปํ•˜๋ฉด:

ํ•ด๋‹น Loader๊ฐ€ ๋กœ๋”ฉํ•œ ๋ชจ๋“  ํด๋ž˜์Šค๋„ GC ๋ถˆ๊ฐ€

์ƒํƒœ๊ฐ€ ๋œ๋‹ค.

๋Œ€ํ‘œ ์›์ธ:

  • static ๊ฐ์ฒด

  • ThreadLocal

  • JDBC Driver ๋“ฑ๋ก ๋ˆ„๋ฝ

  • Cache ๊ฐ์ฒด


์‹ค์ œ ์žฅ์•  ์‚ฌ๋ก€

์žฌ๋ฐฐํฌ ๋ฐ˜๋ณต ํ›„:

1
java.lang.OutOfMemoryError: Metaspace

๋ฐœ์ƒ.

์›์ธ:

  • ์ด์ „ WebApp ClassLoader ๋ฏธํ•ด์ œ

  • static cache ์ฐธ์กฐ ์œ ์ง€

์ฆ‰:

ํด๋ž˜์Šค ์ž์ฒด๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜

๋˜๋Š” ์ƒํ™ฉ์ด๋‹ค.


์„ฑ๋Šฅ ๊ด€์ 

ClassLoader ์ž์ฒด๋Š” ๋นˆ๋ฒˆํ•˜์ง€ ์•Š๋‹ค.

ํ•˜์ง€๋งŒ:

  • reflection ๋‚จ์šฉ

  • proxy ๊ณผ๋‹ค ์ƒ์„ฑ

  • excessive dynamic loading

์€ startup latency๋ฅผ ์ฆ๊ฐ€์‹œํ‚จ๋‹ค.

Spring Boot ์ดˆ๊ธฐ ๊ธฐ๋™์ด ๋А๋ฆฐ ์ด์œ  ์ค‘ ํ•˜๋‚˜๋‹ค.


Trade-off

์žฅ์ 

  • ์œ ์—ฐ์„ฑ

  • ๋Ÿฐํƒ€์ž„ ํ™•์žฅ

  • ํ”Œ๋Ÿฌ๊ทธ์ธ ๊ตฌ์กฐ

  • ๋™์  ์‹œ์Šคํ…œ

๋‹จ์ 

  • startup ๋น„์šฉ ์ฆ๊ฐ€

  • ๋Ÿฐํƒ€์ž„ ์˜ค๋ฅ˜ ์ฆ๊ฐ€

  • ๋””๋ฒ„๊น… ๋‚œ์ด๋„ ์ƒ์Šน

  • classloader leak ์œ„ํ—˜


์ž์ฃผ ๋ฐœ์ƒํ•˜๋Š” ์‹ค์ˆ˜

1. Reflection ๋‚จ์šฉ

๋ถˆํ•„์š”ํ•œ reflection ๋ฐ˜๋ณต ํ˜ธ์ถœ.


2. static ๊ฐ์ฒด ๋ˆ„์ˆ˜

์žฌ๋ฐฐํฌ ํ™˜๊ฒฝ์—์„œ ์น˜๋ช…์ .


3. custom ClassLoader ๋‚จ๋ฐœ

๋งค์šฐ ๋ณต์žกํ•œ ๋””๋ฒ„๊น… ์œ ๋ฐœ.


๋ฉด์ ‘ ๊ผฌ๋ฆฌ ์งˆ๋ฌธ

Q1. ๋ถ€๋ชจ ์œ„์ž„ ๋ชจ๋ธ์€ ์™œ ํ•„์š”ํ•œ๊ฐ€?

ํ•ต์‹ฌ:

  • ๋ณด์•ˆ

  • ์ค‘๋ณต ๋กœ๋”ฉ ๋ฐฉ์ง€

  • Java Core ๋ณดํ˜ธ


Q2. ๊ฐ™์€ ํด๋ž˜์Šค์ธ๋ฐ ์™œ ClassCastException์ด ๊ฐ€๋Šฅํ•œ๊ฐ€?

ํ•ต์‹ฌ:

1
ํด๋ž˜์Šค + ClassLoader

์กฐํ•ฉ์ด ํƒ€์ž… ์‹๋ณ„ ๊ธฐ์ค€์ด๋‹ค.


Q3. Spring์€ ์™œ Reflection์„ ์‚ฌ์šฉํ•˜๋Š”๊ฐ€?

ํ•ต์‹ฌ:

  • ๋Ÿฐํƒ€์ž„ DI

  • Annotation ๊ธฐ๋ฐ˜ ์ฒ˜๋ฆฌ

  • ์œ ์—ฐ์„ฑ ํ™•๋ณด


Q4. Reflection์€ ์™œ ๋А๋ฆฐ๊ฐ€?

ํ•ต์‹ฌ:

  • ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ์ ‘๊ทผ

  • ๋™์  ํ˜ธ์ถœ

  • ์ตœ์ ํ™” ์ œํ•œ


์ข‹์€ ๋‹ต๋ณ€ ์˜ˆ์‹œ

JVM์€ Runtime ์‹œ์ ์— ClassLoader๋ฅผ ํ†ตํ•ด ํด๋ž˜์Šค๋ฅผ ๋กœ๋”ฉํ•ฉ๋‹ˆ๋‹ค.
Java๋Š” ๋ถ€๋ชจ ์œ„์ž„ ๋ชจ๋ธ์„ ํ†ตํ•ด ํ•ต์‹ฌ ํด๋ž˜์Šค๋ฅผ ๋ณดํ˜ธํ•˜๋ฉฐ ์ค‘๋ณต ๋กœ๋”ฉ์„ ๋ฐฉ์ง€ํ•ฉ๋‹ˆ๋‹ค.
๋˜ํ•œ Runtime Dynamic Loading ๊ตฌ์กฐ ๋•๋ถ„์— Spring, JDBC, WAS ๊ฐ™์€ ์œ ์—ฐํ•œ ํ”„๋ ˆ์ž„์›Œํฌ ๊ตฌ์กฐ๊ฐ€ ๊ฐ€๋Šฅํ•ด์กŒ์Šต๋‹ˆ๋‹ค.
๋‹ค๋งŒ Reflection๊ณผ Dynamic Loading์€ startup ๋น„์šฉ๊ณผ ClassLoader leak ๊ฐ™์€ ์šด์˜ ์ด์Šˆ๋ฅผ ์œ ๋ฐœํ•  ์ˆ˜ ์žˆ์–ด ์ฃผ์˜๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.


๊ด€๋ จ CS ๊ฐœ๋… ์—ฐ๊ฒฐ

์—ฐ๊ฒฐ๋˜๋Š” ํ•ต์‹ฌ ๊ฐœ๋…:

  • Dynamic Linking

  • Runtime System

  • Virtual Machine

  • Memory Management

  • Plugin Architecture

  • Dependency Injection

  • Proxy Pattern


ํ˜„์—…์—์„œ ํŠนํžˆ ์ค‘์š”ํ•œ ํฌ์ธํŠธ

1. Spring ๋‚ด๋ถ€ ๋™์ž‘ ์ดํ•ด

๋Œ€๋ถ€๋ถ„ Reflection ๊ธฐ๋ฐ˜.


2. ์žฌ๋ฐฐํฌ ํ™˜๊ฒฝ Memory Leak

์šด์˜ ์žฅ์• ๋กœ ์ง๊ฒฐ๋œ๋‹ค.


3. startup latency

MSA ํ™˜๊ฒฝ์—์„œ ์ค‘์š”ํ•ด์ง„๋‹ค.


ํ•ต์‹ฌ ์š”์•ฝ

  • Java๋Š” Runtime Dynamic Loading ๊ธฐ๋ฐ˜

  • ClassLoader๋Š” JVM ํ•ต์‹ฌ ๋ฉ”์ปค๋‹ˆ์ฆ˜

  • ๋ถ€๋ชจ ์œ„์ž„ ๋ชจ๋ธ์€ ๋ณด์•ˆ๊ณผ ์•ˆ์ •์„ฑ์„ ์œ„ํ•œ ๊ตฌ์กฐ

  • Spring ๋‚ด๋ถ€๋Š” Reflection ๊ธฐ๋ฐ˜

  • Dynamic Loading์€ ์œ ์—ฐ์„ฑ์„ ์ œ๊ณตํ•˜์ง€๋งŒ ์šด์˜ ๋ณต์žก์„ฑ์„ ์ฆ๊ฐ€์‹œํ‚จ๋‹ค

  • ClassLoader leak์€ ์‹ค์ œ ์šด์˜ ์žฅ์•  ์›์ธ์ด๋‹ค

  • ์‹ค๋ฌด์—์„œ๋Š” โ€œ์™œ ์ด๋Ÿฐ ๊ตฌ์กฐ์ธ๊ฐ€?โ€๋ฅผ ์„ค๋ช… ๊ฐ€๋Šฅํ•ด์•ผ ํ•œ๋‹ค

This post is licensed under CC BY 4.0 by the author.