Post

๐Ÿ“‘ JAVA 03 - JVM GC์™€ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ

๐Ÿ“‘ JAVA 03 - JVM GC์™€ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ

JVM GC์™€ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ

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

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

โ€œGC๋Š” ์•ˆ ์“ฐ๋Š” ๊ฐ์ฒด๋ฅผ ์ œ๊ฑฐํ•˜๋Š” ๊ธฐ๋Šฅโ€

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

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

  • ์™œ GC๊ฐ€ ํ•„์š”ํ•œ๊ฐ€?

  • JVM์€ ์™œ Heap์„ ์„ธ๋Œ€๋ณ„๋กœ ๋‚˜๋ˆ„๋Š”๊ฐ€?

  • Minor GC์™€ Major GC ์ฐจ์ด๋Š” ๋ฌด์—‡์ธ๊ฐ€?

  • Stop-The-World๋Š” ์™œ ๋ฐœ์ƒํ•˜๋Š”๊ฐ€?

  • G1GC๋Š” ์™œ ๋“ฑ์žฅํ–ˆ๋Š”๊ฐ€?

  • ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๋Š” ์™œ ๋ฐœ์ƒํ•˜๋Š”๊ฐ€?

  • ์šด์˜ ํ™˜๊ฒฝ์—์„œ GC๋Š” ์–ด๋–ป๊ฒŒ ์žฅ์• ๊ฐ€ ๋˜๋Š”๊ฐ€?

์ฆ‰:

โ€œJava ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ ์‹œ์Šคํ…œ ์ „์ฒดโ€

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


JVM ๋ฉ”๋ชจ๋ฆฌ ๊ตฌ์กฐ ๋ณต์Šต

flowchart TD

    A[JVM Memory]

    A --> B[Heap]
    A --> C[Stack]
    A --> D[Method Area]
    A --> E[Native Memory]

์ด๋ฒˆ ํ•ต์‹ฌ์€ Heap ์˜์—ญ์ด๋‹ค.


Heap ๊ตฌ์กฐ

Heap์€ ๊ฐ์ฒด ์ €์žฅ ์˜์—ญ์ด๋‹ค.

flowchart LR

    A[Heap]

    A --> B[Young Generation]
    A --> C[Old Generation]

์™œ Heap์„ ๋‚˜๋ˆด๋Š”๊ฐ€?

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

โ€œ๋Œ€๋ถ€๋ถ„ ๊ฐ์ฒด๋Š” ๊ธˆ๋ฐฉ ์ฃฝ๋Š”๋‹คโ€

๋ผ๋Š” ๊ฒฝํ—˜์  ํ†ต๊ณ„ ๋•Œ๋ฌธ์ด๋‹ค.

์˜ˆ:

  • HTTP Request ๊ฐ์ฒด

  • DTO

  • StringBuilder

  • ์ž„์‹œ Collection

๋Œ€๋ถ€๋ถ„ ์š”์ฒญ ์ฒ˜๋ฆฌ ํ›„ ๋ฐ”๋กœ ์ œ๊ฑฐ๋œ๋‹ค.

์ฆ‰:

์งง๊ฒŒ ์‚ฌ๋Š” ๊ฐ์ฒด์™€ ์˜ค๋ž˜ ์‚ฌ๋Š” ๊ฐ์ฒด๋ฅผ ๋ถ„๋ฆฌํ•˜๋ฉด GC ํšจ์œจ์ด ์˜ฌ๋ผ๊ฐ„๋‹ค.


Young Generation ๊ตฌ์กฐ

flowchart LR

    A[Eden]
    B[Survivor 0]
    C[Survivor 1]

    A --> B
    A --> C

๊ฐ์ฒด ์ƒ์„ฑ ํ๋ฆ„

flowchart TD

    A[๊ฐ์ฒด ์ƒ์„ฑ]
        --> B[Eden ์ €์žฅ]

    B --> C{GC ๋ฐœ์ƒ}

    C -->|์‚ด์•„์žˆ์Œ| D[Survivor ์ด๋™]
    C -->|์ฃฝ์Œ| E[๋ฉ”๋ชจ๋ฆฌ ์ œ๊ฑฐ]

    D --> F{์˜ค๋ž˜ ์‚ด์•„๋‚จ์Œ?}

    F -->|YES| G[Old Generation ์ด๋™]

Minor GC

Young Generation ๋Œ€์ƒ์œผ๋กœ ์ˆ˜ํ–‰.

ํŠน์ง•:

  • ๋น ๋ฆ„

  • ์ž์ฃผ ๋ฐœ์ƒ

  • ๋Œ€๋ถ€๋ถ„ ๊ฐ์ฒด ์ œ๊ฑฐ ๊ฐ€๋Šฅ

์™œ ๋น ๋ฅผ๊นŒ?

๋Œ€๋ถ€๋ถ„ ๊ฐ์ฒด๊ฐ€ ์ด๋ฏธ ์ฃฝ์–ด์žˆ๊ธฐ ๋•Œ๋ฌธ

์ด๋‹ค.


Stop-The-World(STW)

GC ์‹œ JVM์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ Thread๋ฅผ ๋ฉˆ์ถ˜๋‹ค.

sequenceDiagram

    Application->>JVM: ๊ฐ์ฒด ์‚ฌ์šฉ ์ค‘

    JVM->>All Threads: Stop-The-World

    JVM->>Heap: GC ์ˆ˜ํ–‰

    JVM->>All Threads: Resume

์™œ ๋ฉˆ์ถฐ์•ผ ํ•˜๋Š”๊ฐ€?

GC๋Š”:

โ€œํ˜„์žฌ ์–ด๋–ค ๊ฐ์ฒด๊ฐ€ ์‚ด์•„์žˆ๋Š”๊ฐ€?โ€

๋ฅผ ์ •ํ™•ํžˆ ์•Œ์•„์•ผ ํ•œ๋‹ค.

๊ทธ๋Ÿฐ๋ฐ Thread๊ฐ€ ๊ณ„์† ๊ฐ์ฒด๋ฅผ ๋ณ€๊ฒฝํ•˜๋ฉด:

  • ์ฐธ์กฐ ๊ด€๊ณ„ ๋ณ€๊ฒฝ

  • ๊ฐ์ฒด ์ƒ์„ฑ

  • ๊ฐ์ฒด ์‚ญ์ œ

๊ฐ€ ๊ณ„์† ๋ฐœ์ƒํ•œ๋‹ค.

์ฆ‰:

๋ฉ”๋ชจ๋ฆฌ ์ƒํƒœ๊ฐ€ ๊ณ„์† ๋ฐ”๋€๋‹ค.

๊ทธ๋ž˜์„œ ์•ˆ์ „ํ•œ ๋ถ„์„์„ ์œ„ํ•ด ์ž ์‹œ ๋ฉˆ์ถ˜๋‹ค.


์‹ค๋ฌด์—์„œ STW๊ฐ€ ์œ„ํ—˜ํ•œ ์ด์œ 

์˜ˆ:

  • API ์‘๋‹ต ์ง€์—ฐ

  • Timeout ์ฆ๊ฐ€

  • TPS ๊ฐ์†Œ

  • ์žฅ์•  ์ „ํŒŒ

ํŠนํžˆ ๋Œ€์šฉ๋Ÿ‰ ์„œ๋น„์Šค์—์„œ:

1
STW 5์ดˆ

๊ฐ™์€ ์ƒํ™ฉ์€ ์น˜๋ช…์ ์ด๋‹ค.


Old Generation

์˜ค๋ž˜ ์‚ด์•„๋‚จ์€ ๊ฐ์ฒด ์ €์žฅ ์˜์—ญ.

๋Œ€ํ‘œ:

  • Cache

  • Singleton Bean

  • Session

  • ์žฅ๊ธฐ ์œ ์ง€ Collection


Major GC / Full GC

Old Generation ๋Œ€์ƒ GC.

ํŠน์ง•:

  • ๋А๋ฆผ

  • STW ๊ธธ์–ด์ง

  • ์‹œ์Šคํ…œ ์˜ํ–ฅ ํผ


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

Old ์˜์—ญ ๊ฐ์ฒด๋Š”:

  • ํฌ๊ณ 

  • ์ฐธ์กฐ ๊ด€๊ณ„ ๋ณต์žกํ•˜๊ณ 

  • ์‚ด์•„์žˆ๋Š” ๊ฐ์ฒด ๋น„์œจ ๋†’๋‹ค

์ฆ‰:

GC ํƒ์ƒ‰ ๋น„์šฉ์ด ๋งค์šฐ ์ปค์ง„๋‹ค.


์‹ค์ œ ์šด์˜ ์žฅ์•  ์‚ฌ๋ก€

1
2
3
4
Full GC ๋ฐœ์ƒ
โ†’ STW 10์ดˆ
โ†’ API Timeout
โ†’ ์žฅ์•  ์ „ํŒŒ

์‹ค์ œ ํ˜„์—…์—์„œ ๋งค์šฐ ํ”ํ•œ ์žฅ์•  ํŒจํ„ด์ด๋‹ค.


G1GC ๋“ฑ์žฅ ๋ฐฐ๊ฒฝ

๊ธฐ์กด GC ๋ฌธ์ œ:

  • Heap ์ปค์งˆ์ˆ˜๋ก Full GC ๊ธธ์–ด์ง

  • ์˜ˆ์ธก ๋ถˆ๊ฐ€๋Šฅํ•œ STW

์ด๋ฅผ ํ•ด๊ฒฐํ•˜๋ ค๊ณ  ๋“ฑ์žฅ.


G1GC ๊ตฌ์กฐ

Heap์„ Region ๋‹จ์œ„๋กœ ๋‚˜๋ˆˆ๋‹ค.

flowchart TD

    A[Heap]

    A --> B[Region 1]
    A --> C[Region 2]
    A --> D[Region 3]
    A --> E[Region N]

์™œ ์ข‹์€๊ฐ€?

๊ธฐ์กด:

Heap ์ „์ฒด GC

G1GC:

ํ•„์š”ํ•œ Region ์šฐ์„  GC

์ฆ‰:

  • pause time ์˜ˆ์ธก ๊ฐ€๋Šฅ

  • ๋Œ€์šฉ๋Ÿ‰ Heap ๋Œ€์‘ ๊ฐ€๋Šฅ


G1GC ํ•ต์‹ฌ ์ฒ ํ•™

โ€œGC Throughputโ€๋ณด๋‹ค
โ€œPause Time ์ œ์–ดโ€

๋ฅผ ๋” ์ค‘์š”ํ•˜๊ฒŒ ๋ณธ๋‹ค.

์‹ค๋ฌด์—์„œ ์ด๊ฒŒ ๋งค์šฐ ์ค‘์š”ํ•˜๋‹ค.

์™œ๋ƒ๋ฉด:

์‚ฌ์šฉ์ž๋Š” TPS๋ณด๋‹ค:

์‘๋‹ต ์ง€์—ฐ(latency)

์— ๋ฏผ๊ฐํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.


GC Root

GC๋Š” ๊ฐ์ฒด ์ƒ์กด ์—ฌ๋ถ€๋ฅผ:

โ€œGC Root์—์„œ ๋„๋‹ฌ ๊ฐ€๋Šฅํ•œ๊ฐ€?โ€

๋กœ ํŒ๋‹จํ•œ๋‹ค.

๋Œ€ํ‘œ GC Root:

  • Stack ์ง€์—ญ ๋ณ€์ˆ˜

  • static ๋ณ€์ˆ˜

  • Thread

  • JNI ์ฐธ์กฐ


๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜(Memory Leak)

Java๋„ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

๋งŽ์ด ์˜คํ•ดํ•˜๋Š” ๋ถ€๋ถ„์ด๋‹ค.


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

Java์—์„œ leak์€:

โ€œ์‚ฌ์šฉ ์•ˆ ํ•˜์ง€๋งŒ ์ฐธ์กฐ๊ฐ€ ๋‚จ์•„์žˆ๋Š” ๊ฐ์ฒดโ€

๋‹ค.

์ฆ‰:

GC ๋Œ€์ƒ์ด ์•ˆ ๋œ๋‹ค.


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

1. static Collection

1
2
private static List<Object> cache =
    new ArrayList<>();

๊ณ„์† ์ถ”๊ฐ€๋งŒ ํ•˜๋ฉด ์˜์›ํžˆ ์‚ด์•„์žˆ๋‹ค.


2. ThreadLocal Leak

์‹ค๋ฌด ๋‹จ๊ณจ.

1
2
ThreadLocal<User> local =
    new ThreadLocal<>();

remove() ์•ˆ ํ•˜๋ฉด Thread Pool ํ™˜๊ฒฝ์—์„œ ๋ˆ„์ˆ˜ ๊ฐ€๋Šฅ.


3. Cache ๋ฌดํ•œ ์ฆ๊ฐ€

1
Map<String, Object> cache

eviction ์—†์œผ๋ฉด ์œ„ํ—˜.


์šด์˜์—์„œ ์ค‘์š”ํ•œ GC ๋กœ๊ทธ

์‹ค๋ฌด์—์„œ๋Š” GC ๋กœ๊ทธ๋ฅผ ๋ฐ˜๋“œ์‹œ ๋ณธ๋‹ค.

๋Œ€ํ‘œ ํ™•์ธ ํ•ญ๋ชฉ:

  • STW ์‹œ๊ฐ„

  • Young GC ๋นˆ๋„

  • Full GC ๋นˆ๋„

  • Heap ์‚ฌ์šฉ๋Ÿ‰

  • Promotion ์‹คํŒจ


์˜ˆ์‹œ ๋กœ๊ทธ

1
2
Pause Young (G1 Evacuation Pause)
35ms

์„ฑ๋Šฅ ๊ด€์ 

GC ํ•ต์‹ฌ ๋ชฉํ‘œ:

  • Throughput

  • Latency

  • Memory Footprint

์ด ์…‹์€ Trade-off ๊ด€๊ณ„๋‹ค.


Trade-off

Heap ํฌ๊ฒŒ ์„ค์ •

์žฅ์ :

  • GC ๋นˆ๋„ ๊ฐ์†Œ

๋‹จ์ :

  • Full GC ๊ธธ์–ด์ง

Heap ์ž‘๊ฒŒ ์„ค์ •

์žฅ์ :

  • pause ์งง์Œ

๋‹จ์ :

  • GC ์ž์ฃผ ๋ฐœ์ƒ

G1GC ์‚ฌ์šฉ

์žฅ์ :

  • pause ์˜ˆ์ธก ๊ฐ€๋Šฅ

๋‹จ์ :

  • CPU ์‚ฌ์šฉ๋Ÿ‰ ์ฆ๊ฐ€ ๊ฐ€๋Šฅ

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

1. Heap๋งŒ ๋ฌด์กฐ๊ฑด ํฌ๊ฒŒ ์„ค์ •

์šด์˜ ์žฅ์•  ์›์ธ ๊ฐ€๋Šฅ.


2. Cache ๋ฌดํ•œ ์ฆ๊ฐ€

๋งค์šฐ ํ”ํ•จ.


3. ThreadLocal remove ๋ˆ„๋ฝ

์‹ค๋ฌด ๋‹จ๊ณจ ์žฅ์• .


4. Full GC ๋ฌด์‹œ

์žฅ์•  ์ „์กฐ ์‹ ํ˜ธ ๋†“์นจ.


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

Q1. ์™œ Young/Old ์˜์—ญ์„ ๋‚˜๋ˆ„๋Š”๊ฐ€?

ํ•ต์‹ฌ:

๋Œ€๋ถ€๋ถ„ ๊ฐ์ฒด๋Š” ๋นจ๋ฆฌ ์ฃฝ๊ธฐ ๋•Œ๋ฌธ


Q2. Stop-The-World๋Š” ์™œ ํ•„์š”ํ•œ๊ฐ€?

ํ•ต์‹ฌ:

  • ๊ฐ์ฒด ์ฐธ์กฐ ์•ˆ์ •์„ฑ ํ™•๋ณด

  • GC ์ •ํ™•์„ฑ ๋ณด์žฅ


Q3. Full GC๊ฐ€ ์œ„ํ—˜ํ•œ ์ด์œ ๋Š”?

ํ•ต์‹ฌ:

  • ๊ธด STW

  • ์„œ๋น„์Šค ์‘๋‹ต ์ง€์—ฐ

  • ์žฅ์•  ์ „ํŒŒ


Q4. Java๋„ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋Š”๊ฐ€?

ํ•ต์‹ฌ:

์ฐธ์กฐ๊ฐ€ ๋‚จ์•„์žˆ์œผ๋ฉด GC๋˜์ง€ ์•Š๋Š”๋‹ค.


Q5. G1GC๋Š” ์™œ ๋“ฑ์žฅํ–ˆ๋Š”๊ฐ€?

ํ•ต์‹ฌ:

  • ๋Œ€์šฉ๋Ÿ‰ Heap ๋Œ€์‘

  • Pause Time ์˜ˆ์ธก ๊ฐ€๋Šฅ์„ฑ ํ™•๋ณด


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

JVM์€ ๊ฐ์ฒด ์ˆ˜๋ช… ํŠน์„ฑ์„ ์ด์šฉํ•˜๊ธฐ ์œ„ํ•ด Heap์„ Young/Old ์˜์—ญ์œผ๋กœ ๋ถ„๋ฆฌํ•ฉ๋‹ˆ๋‹ค.
๋Œ€๋ถ€๋ถ„ ๊ฐ์ฒด๋Š” ๋น ๋ฅด๊ฒŒ ์ œ๊ฑฐ๋˜๋ฏ€๋กœ Young GC๋Š” ๋งค์šฐ ํšจ์œจ์ ์ž…๋‹ˆ๋‹ค.
๋ฐ˜๋ฉด Old ์˜์—ญ GC๋Š” STW ์‹œ๊ฐ„์ด ๊ธธ์–ด ์‹ค์ œ ์šด์˜ ์žฅ์•  ์›์ธ์ด ๋  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.
์ด๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ ์œ„ํ•ด G1GC ๊ฐ™์€ Region ๊ธฐ๋ฐ˜ GC๊ฐ€ ๋“ฑ์žฅํ–ˆ์œผ๋ฉฐ, ์ตœ๊ทผ JVM์€ Throughput๋ณด๋‹ค Latency ์•ˆ์ •์„ฑ์„ ์ค‘์š”ํ•˜๊ฒŒ ๋ณด๋Š” ๋ฐฉํ–ฅ์œผ๋กœ ๋ฐœ์ „ํ•˜๊ณ  ์žˆ์Šต๋‹ˆ๋‹ค.


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

  • Garbage Collection

  • Reachability Analysis

  • Memory Management

  • Runtime System

  • Stop-The-World

  • Latency vs Throughput

  • Generational Hypothesis


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

1. GC๋Š” ์šด์˜ ์žฅ์•  ์›์ธ์ด๋‹ค

๋‹จ์ˆœ CS ์ด๋ก ์ด ์•„๋‹ˆ๋‹ค.


2. Full GC๋Š” ๋ฐ˜๋“œ์‹œ ์ถ”์ ํ•ด์•ผ ํ•œ๋‹ค

์žฅ์•  ์ „์กฐ์ผ ๊ฐ€๋Šฅ์„ฑ ๋†’๋‹ค.


3. ThreadLocal Leak ๋งค์šฐ ํ”ํ•˜๋‹ค

ํŠนํžˆ Spring + Thread Pool ํ™˜๊ฒฝ.


4. Latency ๊ด€์ ์ด ์ค‘์š”ํ•˜๋‹ค

์‹ค๋ฌด๋Š” TPS๋ณด๋‹ค ์‘๋‹ต ์ง€์—ฐ์ด ์ค‘์š”ํ•  ๋•Œ ๋งŽ๋‹ค.


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

  • JVM์€ ๊ฐ์ฒด ์ˆ˜๋ช… ํŠน์„ฑ์„ ์ด์šฉํ•ด ์„ธ๋Œ€๋ณ„ GC ์ˆ˜ํ–‰

  • Minor GC๋Š” ๋น ๋ฅด๊ณ  Major GC๋Š” ์œ„ํ—˜ํ•˜๋‹ค

  • Stop-The-World๋Š” GC ์ •ํ™•์„ฑ์„ ์œ„ํ•œ ๊ตฌ์กฐ

  • G1GC๋Š” Pause Time ์ œ์–ด๋ฅผ ์œ„ํ•ด ๋“ฑ์žฅ

  • Java๋„ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค

  • GC๋Š” ์‹ค์ œ ์šด์˜ ์žฅ์• ์™€ ๋งค์šฐ ๋ฐ€์ ‘ํ•˜๋‹ค

  • ์‹ค๋ฌด์—์„œ๋Š” GC ๋กœ๊ทธ ๋ถ„์„ ๋Šฅ๋ ฅ์ด ์ค‘์š”ํ•˜๋‹ค

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