Post

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

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

JVM ClassLoader์™€ Proxy ๊ตฌ์กฐ

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

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

  • JVM์€ ์™œ Runtime Dynamic Loading ๊ตฌ์กฐ๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๊ฐ€?
  • ๋ถ€๋ชจ ์œ„์ž„ ๋ชจ๋ธ์€ ์™œ ํ•„์š”ํ•œ๊ฐ€?
  • ํ•ต์‹ฌ ํด๋ž˜์Šค๋ฅผ ์™œ ๋ณดํ˜ธํ•ด์•ผ ํ•˜๋Š”๊ฐ€?
  • Proxy๋Š” ์™œ ์‚ฌ์šฉํ•˜๋Š”๊ฐ€?
  • Spring์€ ์™œ ํ”„๋ก์‹œ ๊ธฐ๋ฐ˜ ํ”„๋ ˆ์ž„์›Œํฌ์ธ๊ฐ€?
  • Reflection๊ณผ Proxy๋Š” ์–ด๋–ค ๊ด€๊ณ„์ธ๊ฐ€?
  • ์šด์˜ ํ™˜๊ฒฝ์—์„œ ์–ด๋–ค ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋Š”๊ฐ€?

๋ฅผ ์—ฐ๊ฒฐํ•ด์„œ ์ดํ•ดํ•˜๋Š” ๊ฒƒ์ด๋‹ค.

์ฆ‰:

Java Runtime System ์ „์ฒด ํ๋ฆ„

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


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

1
2
3
4
5
6
7
8
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 ๊ตฌ์กฐ

1
2
3
4
5
flowchart TD

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

1. Bootstrap ClassLoader

๊ฐ€์žฅ ์ตœ์ƒ์œ„ ๋กœ๋”.

ํ•ต์‹ฌ Java ํด๋ž˜์Šค๋ฅผ ๋กœ๋”ฉํ•œ๋‹ค.

๋Œ€ํ‘œ:

  • java.lang
  • java.util
  • java.io

์˜ˆ:

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

๊ฒฐ๊ณผ:

1
null

Bootstrap Loader๋Š” Native(C++) ๊ธฐ๋ฐ˜์ด๋ผ null๋กœ ํ‘œํ˜„๋œ๋‹ค.


2. Platform ClassLoader

Java 9 ์ด์ „์—๋Š” Extension Loader์˜€๋‹ค.

์—ญํ• :

JDK ํ”Œ๋žซํผ ๊ธฐ๋Šฅ ๊ด€๋ จ ํด๋ž˜์Šค ๋กœ๋”ฉ

๋Œ€ํ‘œ:

  • java.sql
  • java.xml
  • crypto
  • logging

์ฆ‰:

Bootstrap์€ JVM ์ƒ์กด ํ•ต์‹ฌ,
Platform์€ ํ”Œ๋žซํผ ๊ธฐ๋Šฅ ํ™•์žฅ์ด๋‹ค.


3. Application ClassLoader

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

1
2
3
4
5
6
7
8
public class Main {

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

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

ClassLoader์˜ ํ•ต์‹ฌ ์„ค๊ณ„๋‹ค.

1
2
3
4
5
6
7
8
9
flowchart TD

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

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

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

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

ํ•ต์‹ฌ ๋ชฉ์ ์€:

  • ๋ณด์•ˆ
  • JVM ์•ˆ์ •์„ฑ
  • ํƒ€์ž… ์•ˆ์ •์„ฑ
  • ํด๋ž˜์Šค ์ค‘๋ณต ๋ฐฉ์ง€

์ด๋‹ค.


ํ•ต์‹ฌ ํด๋ž˜์Šค๋ฅผ ์™œ ๋ณดํ˜ธํ•ด์•ผ ํ•˜๋Š”๊ฐ€?

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

1
2
3
4
package java.lang;

public class String {
}

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

๊ทธ๋Ÿฌ๋ฉด JVM์€:

  • ์ง„์งœ String
  • ๊ฐ€์งœ String

์ค‘ ์–ด๋–ค ๊ฑธ ์จ์•ผ ํ• ์ง€ ๋ชจ๋ฅธ๋‹ค.


์™œ ์œ„ํ—˜ํ•œ๊ฐ€?

1. JVM ์‹ ๋ขฐ์„ฑ ๋ถ•๊ดด

Java๋Š”:

  • Object
  • String
  • Thread
  • Class

๊ฐ™์€ ํ•ต์‹ฌ ํด๋ž˜์Šค ๊ธฐ๋ฐ˜์œผ๋กœ ๋™์ž‘ํ•œ๋‹ค.

์ด๊ฒŒ ์œ„์กฐ๋˜๋ฉด JVM ์ „์ฒด ์•ˆ์ •์„ฑ์ด ๋ฌด๋„ˆ์งˆ ์ˆ˜ ์žˆ๋‹ค.


2. ๋ณด์•ˆ ๋ฌธ์ œ

์˜ˆ:

1
java.security.SecurityManager

๊ฐ™์€ ๊ฑธ ์œ„์กฐํ•˜๋ฉด ๊ถŒํ•œ ์‹œ์Šคํ…œ ์ž์ฒด๊ฐ€ ๊นจ์งˆ ์ˆ˜ ์žˆ๋‹ค.


3. ํƒ€์ž… ์•ˆ์ •์„ฑ ๋ถ•๊ดด

Java๋Š”:

โ€œํ•ต์‹ฌ ํด๋ž˜์Šค๋Š” ์•ˆ์ „ํ•˜๋‹คโ€

๋ฅผ ์ „์ œ๋กœ ๋™์ž‘ํ•œ๋‹ค.

ํ•ต์‹ฌ ํด๋ž˜์Šค๊ฐ€ ๋ณ€์กฐ๋˜๋ฉด:

  • equals
  • hashCode
  • casting
  • synchronization

์ „๋ถ€ ์œ„ํ—˜ํ•ด์ง„๋‹ค.


ํด๋ž˜์Šค ์‹๋ณ„ ๊ธฐ์ค€

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

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

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

์ฆ‰:

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


Loading โ†’ Linking โ†’ Initialization

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

1
2
3
4
5
flowchart LR

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

Loading

.class ์ฝ๊ธฐ.


Linking

๊ฒ€์ฆ ๋ฐ ๋ฉ”๋ชจ๋ฆฌ ์—ฐ๊ฒฐ.

์„ธ๋ถ€:

  • Verify
  • Prepare
  • Resolve

Bytecode ๊ฒ€์ฆ์ด ์—ฌ๊ธฐ์„œ ์ˆ˜ํ–‰๋œ๋‹ค.


Initialization

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

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

Runtime Dynamic Loading

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

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

์‹คํ–‰ ์‹œ์ (Runtime)์— ํด๋ž˜์Šค ๋กœ๋”ฉ ๊ฐ€๋Šฅ.


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

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

  • Spring
  • JDBC
  • Tomcat
  • JPA Proxy
  • AOP Proxy

๊ฐ™์€ ๊ฐ•๋ ฅํ•œ ๋Ÿฐํƒ€์ž„ ํ™•์žฅ ๊ตฌ์กฐ๋ฅผ ๊ฐ€์ง„๋‹ค.


Reflection

Reflection์€:

Runtime ์‹œ์ ์— ํด๋ž˜์Šค ์ •๋ณด๋ฅผ ๋ถ„์„/์กฐ์ž‘

ํ•˜๋Š” ๊ธฐ์ˆ ์ด๋‹ค.

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

Method[] methods =
    clazz.getDeclaredMethods();

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

๋Œ€ํ‘œ์ ์œผ๋กœ:

  • Bean ์ƒ์„ฑ
  • DI
  • AOP
  • Annotation ๋ถ„์„

๋•Œ๋ฌธ์ด๋‹ค.

์ฆ‰:

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

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


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

Proxy ํ•ต์‹ฌ์€:

โ€œ์‹ค์ œ ๊ฐ์ฒด ๋Œ€์‹  ํ˜ธ์ถœ์„ ๊ฐ€๋กœ์ฑ„๋Š” ๊ฐ์ฒดโ€

๋‹ค.


์ผ๋ฐ˜ ํ˜ธ์ถœ ๊ตฌ์กฐ

1
2
3
4
flowchart TD

    A[Client]
        --> B[Real Object]

Proxy ๊ตฌ์กฐ

1
2
3
4
5
flowchart TD

    A[Client]
        --> B[Proxy]
        --> C[Real Object]

์ฆ‰:

์ค‘๊ฐ„์— ๋Œ€๋ฆฌ ๊ฐ์ฒด๋ฅผ ๋‘”๋‹ค.


์™œ ๊ตณ์ด Proxy๋ฅผ ์“ฐ๋Š”๊ฐ€?

ํ•ต์‹ฌ ์ด์œ :

๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง ์ˆ˜์ • ์—†์ด ๊ณตํ†ต ๊ธฐ๋Šฅ ์ถ”๊ฐ€

๋‹ค.

๋Œ€ํ‘œ ๊ณตํ†ต ๊ธฐ๋Šฅ:

  • ๋กœ๊ทธ
  • ํŠธ๋žœ์žญ์…˜
  • ๊ถŒํ•œ ๊ฒ€์‚ฌ
  • ์บ์‹œ
  • ์„ฑ๋Šฅ ์ธก์ •

@Transactional ์‹ค์ œ ๊ตฌ์กฐ

1
2
3
@Transactional
public void order() {
}

์‹ค์ œ ๋‚ด๋ถ€ ๊ตฌ์กฐ:

1
2
3
4
5
6
7
8
9
sequenceDiagram

    Client->>Transaction Proxy: order()

    Transaction Proxy->>Transaction Manager: begin()

    Transaction Proxy->>Real Service: order()

    Transaction Proxy->>Transaction Manager: commit()

์ฆ‰:

ํŠธ๋žœ์žญ์…˜ ๋กœ์ง์„ Proxy๊ฐ€ ๋Œ€์‹  ์ˆ˜ํ–‰

ํ•œ๋‹ค.


Spring์ด Proxy๋ฅผ ์‚ฌ์šฉํ•˜๋Š” ์ด์œ 

Spring์€:

  • AOP
  • Transaction
  • Security
  • Cache
  • Async

๊ฑฐ์˜ ๋Œ€๋ถ€๋ถ„ Proxy ๊ธฐ๋ฐ˜์ด๋‹ค.

์ฆ‰:

Spring์€ Proxy Framework์— ๊ฐ€๊น๋‹ค.


Proxy ์ข…๋ฅ˜

1. ์ •์  Proxy

์ง์ ‘ ํด๋ž˜์Šค ์ž‘์„ฑ.

1
2
class PaymentProxy {
}

๋ฌธ์ œ:
๋„ˆ๋ฌด ๊ท€์ฐฎ๋‹ค.


2. ๋™์  Proxy

๋Ÿฐํƒ€์ž„์— ์ž๋™ ์ƒ์„ฑ.

๋Œ€ํ‘œ:

  • JDK Dynamic Proxy
  • CGLIB

JDK Dynamic Proxy

์ธํ„ฐํŽ˜์ด์Šค ๊ธฐ๋ฐ˜.

1
2
public interface UserService {
}

ํ•„์š”.


CGLIB

์ƒ์† ๊ธฐ๋ฐ˜ Proxy.

1
Proxy extends UserService

Spring Boot๋Š” ๋Œ€๋ถ€๋ถ„ CGLIB ์‚ฌ์šฉ.


์‹ค๋ฌด ํ•ต์‹ฌ ๋ฌธ์ œ

self invocation ๋ฌธ์ œ

1
2
3
4
5
6
7
8
@Transactional
public void a() {
    b();
}

@Transactional
public void b() {
}

๋‚ด๋ถ€ ํ˜ธ์ถœ:

1
b();

์€ Proxy๋ฅผ ์•ˆ ํƒ„๋‹ค.

์ฆ‰:

Transaction ์ ์šฉ ์•ˆ๋  ์ˆ˜ ์žˆ๋‹ค.

์ด๊ฑด ๋ฉด์ ‘ ๋‹จ๊ณจ์ด๋‹ค.


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

ClassLoader Memory Leak

ํŠนํžˆ:

  • Tomcat
  • DevTools
  • Hot Reload

ํ™˜๊ฒฝ์—์„œ ์œ ๋ช…ํ•˜๋‹ค.


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

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

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

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

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

  • static ๊ฐ์ฒด
  • ThreadLocal
  • cache ๊ฐ์ฒด

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

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

1
java.lang.OutOfMemoryError: Metaspace

๋ฐœ์ƒ.

์›์ธ:

  • ์ด์ „ WebApp ClassLoader ์ฐธ์กฐ ์œ ์ง€
  • static cache ๋ˆ„์ˆ˜

์„ฑ๋Šฅ ๊ด€์ 

ClassLoader ์ž์ฒด๋Š” ๋ณ‘๋ชฉ์ด ์•„๋‹ˆ๋‹ค.

์‹ค์ œ ๋ฌธ์ œ๋Š”:

  • reflection ๋‚จ์šฉ
  • excessive proxy
  • startup latency ์ฆ๊ฐ€

๋‹ค.

์‹ค์ œ ์šด์˜ ๋ณ‘๋ชฉ์€ ๋Œ€๋ถ€๋ถ„:

  • DB
  • Network
  • External API

๋‹ค.


Trade-off

์žฅ์ 

  • ์œ ์—ฐ์„ฑ
  • ๋Ÿฐํƒ€์ž„ ํ™•์žฅ
  • ๋™์  ๊ตฌ์กฐ
  • ๊ณตํ†ต ๊ด€์‹ฌ์‚ฌ ๋ถ„๋ฆฌ

๋‹จ์ 

  • startup ๋น„์šฉ ์ฆ๊ฐ€
  • ๋Ÿฐํƒ€์ž„ ์˜ค๋ฅ˜ ์ฆ๊ฐ€
  • ๋””๋ฒ„๊น… ์–ด๋ ค์›€
  • classloader leak ์œ„ํ—˜

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

1. Reflection ๋‚จ์šฉ

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


2. self invocation

Proxy ์šฐํšŒ ๋ฌธ์ œ.


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

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


4. final ๋ฉ”์„œ๋“œ ์‚ฌ์šฉ

CGLIB Proxy ๋ถˆ๊ฐ€ ๊ฐ€๋Šฅ์„ฑ.


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

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

ํ•ต์‹ฌ:

  • ๋ณด์•ˆ
  • JVM ์•ˆ์ •์„ฑ
  • Java Core ๋ณดํ˜ธ

Q2. ํ•ต์‹ฌ ํด๋ž˜์Šค๋ฅผ ์™œ ๋ณดํ˜ธํ•ด์•ผ ํ•˜๋Š”๊ฐ€?

ํ•ต์‹ฌ:

  • ํƒ€์ž… ์•ˆ์ •์„ฑ
  • JVM ์‹ ๋ขฐ์„ฑ
  • ๋ณด์•ˆ ์œ ์ง€

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

ํ•ต์‹ฌ:

  • ๊ณตํ†ต ๊ด€์‹ฌ์‚ฌ ๋ถ„๋ฆฌ
  • Transaction/AOP ๊ตฌํ˜„

Q4. self invocation ๋ฌธ์ œ๋ž€?

ํ•ต์‹ฌ:

  • ๋‚ด๋ถ€ ํ˜ธ์ถœ์€ Proxy๋ฅผ ๊ฑฐ์น˜์ง€ ์•Š์Œ

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

JVM์€ Runtime ์‹œ์ ์— ClassLoader๋ฅผ ํ†ตํ•ด ํด๋ž˜์Šค๋ฅผ ๋กœ๋”ฉํ•ฉ๋‹ˆ๋‹ค.
๋ถ€๋ชจ ์œ„์ž„ ๋ชจ๋ธ์„ ํ†ตํ•ด Java ํ•ต์‹ฌ ํด๋ž˜์Šค๋ฅผ ๋ณดํ˜ธํ•˜๋ฉฐ JVM ์•ˆ์ •์„ฑ๊ณผ ํƒ€์ž… ์•ˆ์ •์„ฑ์„ ์œ ์ง€ํ•ฉ๋‹ˆ๋‹ค.
๋˜ํ•œ Spring์€ Proxy์™€ Reflection ๊ธฐ๋ฐ˜์œผ๋กœ ๋™์ž‘ํ•˜๋ฉฐ ์ด๋ฅผ ํ†ตํ•ด Transaction, AOP, Security ๊ฐ™์€ ๊ณตํ†ต ๊ธฐ๋Šฅ์„ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง๊ณผ ๋ถ„๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
๋‹ค๋งŒ Reflection๊ณผ Proxy ๊ตฌ์กฐ๋Š” startup ๋น„์šฉ ์ฆ๊ฐ€์™€ ์šด์˜ ๋ณต์žก์„ฑ์„ ์œ ๋ฐœํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


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

  • Dynamic Linking
  • Runtime System
  • Dependency Injection
  • AOP
  • Proxy Pattern
  • Virtual Machine
  • Plugin Architecture

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

1. Spring ๋‚ด๋ถ€ ๊ตฌ์กฐ ์ดํ•ด

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


2. self invocation ๋ฌธ์ œ

์‹ค๋ฌด ์žฅ์•  ์›์ธ ์ž์ฃผ ๋จ.


3. startup latency

MSA ํ™˜๊ฒฝ์—์„œ ์ค‘์š”.


4. ์žฌ๋ฐฐํฌ Memory Leak

์šด์˜ ์žฅ์•  ํ•ต์‹ฌ ์›์ธ.


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

  • Java๋Š” Runtime Dynamic Loading ๊ธฐ๋ฐ˜
  • ClassLoader๋Š” JVM ํ•ต์‹ฌ ๋ฉ”์ปค๋‹ˆ์ฆ˜
  • ๋ถ€๋ชจ ์œ„์ž„ ๋ชจ๋ธ์€ JVM ์•ˆ์ •์„ฑ์„ ์œ„ํ•œ ๊ตฌ์กฐ
  • Spring ๋‚ด๋ถ€๋Š” Reflection + Proxy ๊ธฐ๋ฐ˜
  • Proxy๋Š” ๊ณตํ†ต ๊ธฐ๋Šฅ ๋ถ„๋ฆฌ๋ฅผ ์œ„ํ•ด ์‚ฌ์šฉ๋œ๋‹ค
  • self invocation์€ ์‹ค๋ฌด ๋‹จ๊ณจ ๋ฌธ์ œ
  • ClassLoader leak์€ ์‹ค์ œ ์šด์˜ ์žฅ์•  ์›์ธ์ด๋‹ค
This post is licensed under CC BY 4.0 by the author.