๐ŸŽฏ1์ฃผ์ฐจ Unit 5.2 โ€” Heap์˜ ์„ธ๋Œ€ ๊ตฌ์กฐ

Psjยท4์ผ ์ „

F-lab

๋ชฉ๋ก ๋ณด๊ธฐ
38/50

๐ŸŽฏ Unit 5.2 โ€” Heap์˜ ์„ธ๋Œ€ ๊ตฌ์กฐ โ˜…โ˜…โ˜…

F-lab Java 1์ฃผ์ฐจ / Phase 5 / Unit 5.2 ๋ณธ๊ฒฉ ํ•™์Šต ์ž๋ฃŒ
9-์„น์…˜ ๋งˆ์Šคํ„ฐ ํ”„๋กฌํ”„ํŠธ ํ˜•์‹์œผ๋กœ ๊นŠ์ด ํŒŒํ—ค์นœ๋‹ค.

์„ ์ˆ˜ ์ง€์‹: Unit 5.1 (GC์˜ ๊ธฐ๋ณธ ๊ฐœ๋…๊ณผ ์•ฝํ•œ ์„ธ๋Œ€ ๊ฐ€์„ค)
๋‹ค์Œ Unit: 5.3 โ€” GC ์•Œ๊ณ ๋ฆฌ์ฆ˜ 4๊ฐ€์ง€

์ด Unit์˜ ์˜๋ฏธ: ์•ฝํ•œ ์„ธ๋Œ€ ๊ฐ€์„ค์˜ ๊ตฌ์ฒด์  ๊ตฌํ˜„.
"Heap์ด ์–ด๋–ป๊ฒŒ ๋‚˜๋‰˜์–ด ์žˆ๊ณ , ๊ฐ์ฒด๊ฐ€ ์–ด๋–ค ์ผ์ƒ์„ ์‚ฌ๋Š”๊ฐ€" ์˜ ์ •ํ™•ํ•œ ์ดํ•ด.
Minor GC vs Major GC vs Full GC ์˜ ์ฐจ์ด โ€” ๋ฉด์ ‘ ๋‹จ๊ณจ.


๐ŸŒ 1. ์„ธ์ƒ ์† ๋น„์œ 

Heap์˜ ์„ธ๋Œ€ ๊ตฌ์กฐ = "๋ณ‘์›์˜ ํ™˜์ž ๊ด€๋ฆฌ"

ํฐ ๋ณ‘์›์„ ์ƒ์ƒํ•ด๋ณด์„ธ์š”. ํ™˜์ž๊ฐ€ ๋“ค์–ด์˜ค๋ฉด ์–ด๋–ป๊ฒŒ ๋ถ„๋ฅ˜ํ• ๊นŒ์š”?

1์ธต โ€” ์‘๊ธ‰์‹ค (Eden):

  • ์ƒˆ ํ™˜์ž๊ฐ€ ์ฒ˜์Œ ๋„์ฐฉํ•˜๋Š” ๊ณณ
  • ๋งค์šฐ ๋ถ๋น”
  • ๋Œ€๋ถ€๋ถ„ ํ™˜์ž๋Š” ๊ธˆ๋ฐฉ ํ‡ด์› (Garbage)
  • ์ผ๋ถ€๋งŒ ์ž…์› ํ•„์š”

2์ธต โ€” ์ผ๋ฐ˜ ๋ณ‘๋™ (Survivor):

  • ์‘๊ธ‰์‹ค์—์„œ ์‚ด์•„๋‚จ์€ ํ™˜์ž
  • ์งง๊ฒŒ ์ž…์› ํ›„ ๋Œ€๋ถ€๋ถ„ ํ‡ด์›
  • ๊ฐ€๋” ์žฅ๊ธฐ ์ž…์› ํ•„์š”ํ•œ ์‚ฌ๋žŒ๋งŒ ๋‹ค์Œ ๋‹จ๊ณ„๋กœ

3์ธต โ€” ์žฅ๊ธฐ ์ž…์› ๋ณ‘๋™ (Old):

  • ์ •๋ง ์˜ค๋ž˜ ์ž…์›ํ•˜๋Š” ํ™˜์ž
  • ๊ฑฐ์˜ ์•ˆ ๋ฐ”๋€œ
  • ๊ฐ€๋”๋งŒ ํฐ ์ •๋ฆฌ (Major GC)

๋ณ‘์›์˜ ์šด์˜ ์›๋ฆฌ:

  • ์‘๊ธ‰์‹ค์€ ์ž์ฃผ ์ฒญ์†Œ (๋“ค๊ณ ๋‚˜๋Š” ์‚ฌ๋žŒ ๋งŽ์Œ)
  • ์ผ๋ฐ˜ ๋ณ‘๋™์€ ๊ฐ€๋” ์ฒญ์†Œ
  • ์žฅ๊ธฐ ๋ณ‘๋™์€ ๊ฑฐ์˜ ์•ˆ ๊ฑด๋“œ๋ฆผ

โ†’ ์ด๊ฒŒ ์ž๋ฐ” Heap์˜ ์„ธ๋Œ€ ๊ตฌ์กฐ.


๋” ๊ตฌ์ฒด์ ์ธ ๋น„์œ  โ€” "์ด์‚ฌ ์‹œ์Šคํ…œ"

์ƒํ™ฉ: ์•„ํŒŒํŠธ๊ฐ€ 3๊ฐœ ์žˆ๋‹ค๊ณ  ์ƒ์ƒ.

์•„ํŒŒํŠธ A (Eden):

  • ์‹ ์ž… ๊ฑฐ์ฃผ์ž๋“ค (์ƒˆ ๊ฐ์ฒด)
  • ๋งค์šฐ ๋นจ๋ฆฌ ์ฐจ๊ณ  ๋งค์šฐ ๋นจ๋ฆฌ ๋น„์›€

์•„ํŒŒํŠธ B & C (Survivor 0, Survivor 1):

  • A ์—์„œ ์‚ด์•„๋‚จ์€ ์‚ฌ๋žŒ๋“ค
  • ๋‘ ์•„ํŒŒํŠธ๊ฐ€ ๋ฒˆ๊ฐˆ์•„ ์‚ฌ์šฉ:
    • ์ง์ˆ˜ ํšŒ์ฐจ: A + B โ†’ C ๋กœ ์ด์‚ฌ
    • ํ™€์ˆ˜ ํšŒ์ฐจ: A + C โ†’ B ๋กœ ์ด์‚ฌ
  • ์ผ์ • ํšŸ์ˆ˜ (์•ฝ 15ํšŒ) ์‚ด์•„๋‚จ์œผ๋ฉด โ†’ ๋‹ค์Œ ๋‹จ๊ณ„

์•„ํŒŒํŠธ D (Old):

  • ์ •๋ง ์˜ค๋ž˜ ์‚ด ์‚ฌ๋žŒ๋“ค
  • ๊ฑฐ์˜ ์•ˆ ๋ฐ”๋€œ
  • ๊ฐ€๋”๋งŒ ํฐ ์ •๋ฆฌ

์™œ Survivor๊ฐ€ 2๊ฐœ?:

  • ํ•œ์ชฝ์€ ํ•ญ์ƒ ๋น„์–ด์žˆ์Œ (๋‹ค์Œ ์ด์‚ฌ ๋ฐ›์„ ์ค€๋น„)
  • ๋‹ค๋ฅธ ์ชฝ์€ ํ˜„์žฌ ๊ฑฐ์ฃผ
  • โ†’ ๋งค๋ฒˆ ์••์ถ• ์—†์ด ๊น”๋”ํ•˜๊ฒŒ ์ด์‚ฌ

โ†’ ์ด๊ฒŒ Eden + Survivor 0/1 ์˜ ์šด์˜ ์›๋ฆฌ.


ํ•ต์‹ฌ ํ•œ ๋ฌธ์žฅ

"์ž๋ฐ” Heap์€ ๊ฐ์ฒด์˜ ์ˆ˜๋ช…์— ๋”ฐ๋ผ ์˜์—ญ์„ ๋‚˜๋ˆ„๊ณ , ๋‹ค๋ฅธ GC ์ „๋žต์„ ์ ์šฉํ•œ๋‹ค."

3๊ฐ€์ง€ ํ•ต์‹ฌ ์˜์—ญ:

  • Eden: ์ƒˆ ๊ฐ์ฒด์˜ ๋ณด๊ธˆ์ž๋ฆฌ
  • Survivor (From/To): 1์ฐจ ์ƒ์กด์ž์˜ ์ž„์‹œ ๊ฑฐ์ฒ˜
  • Old: ์žฅ์ˆ˜ ๊ฐ์ฒด์˜ ์•ˆ์‹์ฒ˜

๋น„์œ  ์ •๋ฆฌ:

๋น„์œ  ์š”์†ŒHeap ์ ์šฉ
์‘๊ธ‰์‹คEden
์ผ๋ฐ˜ ๋ณ‘๋™ (2๊ฐœ)Survivor 0, Survivor 1
์žฅ๊ธฐ ์ž…์› ๋ณ‘๋™Old Generation
์‘๊ธ‰์‹ค ์ฒญ์†ŒMinor GC
์žฅ๊ธฐ ๋ณ‘๋™ ์ฒญ์†ŒMajor GC
์ „์ฒด ์ฒญ์†ŒFull GC

๐Ÿ”ฅ 2. ํƒ„์ƒ ๋ฐฐ๊ฒฝ

์™œ Heap์„ ๋‚˜๋ˆ ์•ผ ํ–ˆ๋‚˜?

Java ์ดˆ๊ธฐ (1.0~1.4) ์˜ GC ๋Š” Heap ์ „์ฒด๋ฅผ ํ•œ ๋ฒˆ์— ์ฒญ์†Œํ–ˆ์Šต๋‹ˆ๋‹ค.

๋ฌธ์ œ:

  • Heap์ด 1GB โ†’ 1GB ์ „์ฒด ์Šค์บ”
  • ์ˆ˜๋ฐฑ ms ~ ์ˆ˜ ์ดˆ์˜ STW
  • ์‚ฌ์šฉ์ž ์‘๋‹ต X

์›์ธ ๋ถ„์„:

  • ์‚ฌ์‹ค ๋Œ€๋ถ€๋ถ„ ๊ฐ์ฒด๋Š” Young (๋ฐฉ๊ธˆ ๋งŒ๋“  ๊ฒƒ)
  • ์˜ค๋ž˜๋œ ๊ฐ์ฒด๋Š” ๊ฑฐ์˜ ๋ณ€ํ•˜์ง€ ์•Š์Œ
  • ๊ฐ™์€ ๋น„์œจ๋กœ ์ฒญ์†Œํ•˜๋Š” ๊ฑด ๋น„ํšจ์œจ

Generational GC ์˜ ๋“ฑ์žฅ (Java 5, 2004)

์•ฝํ•œ ์„ธ๋Œ€ ๊ฐ€์„ค (Unit 5.1) ํ™œ์šฉ:

"๋Œ€๋ถ€๋ถ„ ๊ฐ์ฒด๋Š” ๋‹จ๋ช…, ์‚ด์•„๋‚จ์€ ๊ฒƒ์€ ์žฅ์ˆ˜"

์•„์ด๋””์–ด:

  • Heap ์„ ์„ธ๋Œ€ ๋ณ„๋กœ ๋ถ„๋ฆฌ
  • Young โ†’ ์ž์ฃผ GC, ๋น ๋ฆ„
  • Old โ†’ ๊ฐ€๋” GC, ํฐ ์ •๋ฆฌ

์‹ค์ธก ํšจ๊ณผ:

  • Heap 1GB ์—์„œ๋„ ํ‰๊ท  STW 10ms ์ดํ•˜
  • Throughput 2~3๋ฐฐ ํ–ฅ์ƒ

Eden + Survivor ์˜ ํƒ„์ƒ

์ฒ˜์Œ์—๋Š” Young Generation ์ด ๋‹จ์ˆœํ–ˆ์Šต๋‹ˆ๋‹ค:

  • Young ๊ฐ€๋“ โ†’ ์‚ด์•„์žˆ๋Š” ๊ฐ์ฒด๋ฅผ Old ๋กœ ๋ณต์‚ฌ

๋ฌธ์ œ:

  • ๋„ˆ๋ฌด ๋งŽ์€ ๊ฐ์ฒด๊ฐ€ Old ๋กœ ์ด๋™
  • Old ๊ฐ€ ๋นจ๋ฆฌ ๊ฐ€๋“ โ†’ Major GC ์ž์ฃผ
  • ๋น„ํšจ์œจ

ํ•ด๊ฒฐ โ€” Survivor ์˜์—ญ โญ :

  • Eden ์—์„œ ์‚ด์•„๋‚จ์•˜๋‹ค๊ณ  ๋ฐ”๋กœ Old ๋กœ ๋ณด๋‚ด์ง€ ๋ง๊ณ 
  • Survivor ์— ์ž„์‹œ ๊ฑฐ์ฃผ
  • ์ผ์ • ๊ธฐ๊ฐ„ ๋” ์‚ด์•„๋‚จ์œผ๋ฉด ๊ทธ๋•Œ Old ๋กœ
Eden โ”€โ”€โ†’ Survivor (๋ช‡ ํšŒ) โ”€โ”€โ†’ Old
       (ํ•„ํ„ฐ๋ง)

ํšจ๊ณผ:

  • ์ง„์งœ ์žฅ์ˆ˜ ๊ฐ์ฒด๋งŒ Old ๋กœ
  • Old ๊ฐ€ ์ฒœ์ฒœํžˆ ์ฐธ
  • Major GC ๋นˆ๋„ โ†“

๋‘ ๊ฐœ์˜ Survivor โ€” Copying GC โญ

์™œ Survivor ๊ฐ€ 2๊ฐœ?

๋‹ต: Copying GC ๋ฅผ ํ™œ์šฉํ•˜๊ธฐ ์œ„ํ•ด.

Copying GC:

  • ํ•œ ์˜์—ญ์—์„œ ๋‹ค๋ฅธ ์˜์—ญ์œผ๋กœ ์‚ด์•„์žˆ๋Š” ๊ฐ์ฒด๋งŒ ๋ณต์‚ฌ
  • ์›๋ณธ ์˜์—ญ์€ ํ†ต์งธ๋กœ ๋น„์›€
  • โ†’ ๋‹จํŽธํ™” (Fragmentation) ์ž๋™ ํ•ด์†Œ

Survivor 0 (From) โ†” Survivor 1 (To) ์šด์˜:

Round 1:
  [Eden + Survivor 0] โ†’ Survivor 1
                        (์‚ด์•„๋‚จ์€ ๊ฐ์ฒด ๋ณต์‚ฌ)
  Eden ๋น„์›€, Survivor 0 ๋น„์›€

Round 2:
  [Eden + Survivor 1] โ†’ Survivor 0
                        (์—ญ๋ฐฉํ–ฅ)
  Eden ๋น„์›€, Survivor 1 ๋น„์›€

... ๋ฐ˜๋ณต ...

ํ•ต์‹ฌ:

  • ํ•œ Survivor๋Š” ํ•ญ์ƒ ๋น„์–ด์žˆ์Œ
  • ๋งค๋ฒˆ ๋‹ค๋ฅธ ์ชฝ์œผ๋กœ ๋ณต์‚ฌ
  • ์ž์—ฐ์Šค๋Ÿฌ์šด ์••์ถ• ํšจ๊ณผ

โ†’ ์ด๊ฒŒ Eden + Survivor 0/1 ์˜ ์ •ํ™•ํ•œ ์šด์˜ ์›๋ฆฌ.


Card Table ์˜ ์ •์ฐฉ

๋ฌธ์ œ: Old โ†’ Young ์ฐธ์กฐ๊ฐ€ ์žˆ์„ ์ˆ˜ ์žˆ์Œ.

public class OldObject {
    private YoungObject young;  // Old โ†’ Young ์ฐธ์กฐ
}

Minor GC ์‹œ Young ๋งŒ ๋ณด๋ฉด ์ด ์ฐธ์กฐ๋ฅผ ๋†“์น  ์ˆ˜ ์žˆ์Œ.

ํ•ด๊ฒฐ โ€” Card Table (Unit 5.1 ๋ฏธ๋ฆฌ๋ณด๊ธฐ):

  • Old ์˜์—ญ์„ ์นด๋“œ (512 byte) ๋กœ ๋‚˜๋ˆ”
  • Old โ†’ Young ์ฐธ์กฐ ๋ฐœ์ƒ ์‹œ dirty ๋งˆํ‚น
  • Minor GC ์‹œ dirty ์นด๋“œ๋งŒ ์ถ”๊ฐ€ ์Šค์บ”

โ†’ ์•ฝํ•œ ์„ธ๋Œ€ ๊ฐ€์„ค ๋•๋ถ„์— Old โ†’ Young ์ฐธ์กฐ๋Š” ์ ์Œ โ†’ ํšจ์œจ์ .


ํ•ต์‹ฌ ํ†ต์ฐฐ

"Heap์˜ ์„ธ๋Œ€ ๊ตฌ์กฐ๋Š” ์•ฝํ•œ ์„ธ๋Œ€ ๊ฐ€์„ค์„ ์ •ํ™•ํžˆ ๋ฐ˜์˜ํ•œ ์ •๊ตํ•œ ์‹œ์Šคํ…œ์ด๋‹ค."

Eden + Survivor 0/1 + Old ๋กœ ๋ถ„๋ฆฌ, Copying GC ๋กœ ์ž๋™ ์••์ถ•, Card Table ๋กœ ์„ธ๋Œ€ ๊ฐ„ ์ฐธ์กฐ ์ถ”์ , Promotion ์œผ๋กœ ์ง„์งœ ์žฅ์ˆ˜ ๊ฐ์ฒด ๋ถ„๋ฆฌ. ๋ชจ๋“  ๊ฒฐ์ •์ด "๊ฐ€์„ค์„ ์–ด๋–ป๊ฒŒ ํšจ์œจ์ ์œผ๋กœ ํ™œ์šฉํ• ๊นŒ" ์˜ ๋‹ต.

์ด ๊ตฌ์กฐ๋ฅผ ์ •ํ™•ํžˆ ์ดํ•ดํ•˜๋ฉด GC ์•Œ๊ณ ๋ฆฌ์ฆ˜ (Unit 5.3), GC ์ข…๋ฅ˜ (Unit 5.4), ์šด์˜ ํ™˜๊ฒฝ GC ํŠœ๋‹๊นŒ์ง€ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ํก์ˆ˜.


๐Ÿ’ฃ 3. ์—†์œผ๋ฉด ์ƒ๊ธฐ๋Š” ๋ฌธ์ œ

์„ธ๋Œ€ ๊ตฌ์กฐ๋ฅผ ๋ชจ๋ฅด๋ฉด GC ๊ด€๋ จ ๋ฌธ์ œ ๋ถ„์„์ด ์–ด๋ ต์Šต๋‹ˆ๋‹ค.

์‹œ๋‚˜๋ฆฌ์˜ค 1: Minor GC ๊ฐ€ ์™œ ์ž์ฃผ ๋ฐœ์ƒ?

์šด์˜ ํ™˜๊ฒฝ GC ๋กœ๊ทธ:

GC(0) Pause Young 25M->2M(64M) 5ms
GC(1) Pause Young 27M->3M(64M) 6ms
GC(2) Pause Young 25M->2M(64M) 5ms
... 1์ดˆ๋งˆ๋‹ค ๋ฐœ์ƒ ...

์„ธ๋Œ€ ๊ตฌ์กฐ ๋ชจ๋ฅด๋ฉด:

  • "Minor GC ๊ฐ€ ์™œ ์ด๋ฆฌ ์ž์ฃผ? ๋ฌธ์ œ ์•„๋‹Œ๊ฐ€?"
  • ๋ฌด๋ฆฌํ•˜๊ฒŒ ์•Œ๊ณ ๋ฆฌ์ฆ˜ ๋ณ€๊ฒฝ ์‹œ๋„

์„ธ๋Œ€ ๊ตฌ์กฐ ์•Œ๋ฉด:

  • "Eden ์ด ์ž‘์•„์„œ ๋นจ๋ฆฌ ์ฐธ"
  • "Eden ํ‚ค์šฐ๋ฉด Minor GC ๋นˆ๋„ โ†“"
  • โ†’ -Xmn4g (Young ์˜์—ญ 4GB)
  • ๋˜๋Š” G1 ์˜ ๊ฒฝ์šฐ -XX:NewRatio ์กฐ์ •

์‹œ๋‚˜๋ฆฌ์˜ค 2: Old ์˜์—ญ์ด ๋น ๋ฅด๊ฒŒ ์ฐธ

GC ๋กœ๊ทธ:
GC(0) Pause Young 25M->20M(64M) 5ms  โ† Old๋กœ ๋งŽ์ด Promotion
GC(1) Pause Young 30M->25M(64M) 6ms
...
GC(50) Pause Full 60M->50M(64M) 200ms โ† Full GC ๋ฐœ์ƒ

์„ธ๋Œ€ ๊ตฌ์กฐ ๋ชจ๋ฅด๋ฉด:

  • "์™œ Old ๊ฐ€ ๋นจ๋ฆฌ ์ฐจ์ง€?"

์„ธ๋Œ€ ๊ตฌ์กฐ ์•Œ๋ฉด:

  • "Survivor ๊ฐ€ ์ž‘์•„์„œ ๊ฐ์ฒด๊ฐ€ ๋„ˆ๋ฌด ๋นจ๋ฆฌ Promotion"
  • "๋˜๋Š” Tenuring Threshold ๊ฐ€ ๋‚ฎ์Œ"
  • โ†’ Survivor ํฌ๊ธฐ ์กฐ์ •, threshold ์กฐ์ •

์‹œ๋‚˜๋ฆฌ์˜ค 3: Promotion Failure

GC ๋กœ๊ทธ:
[GC pause (G1 Evacuation Pause) (young) (to-space exhausted)]

์˜๋ฏธ: Survivor ๋˜๋Š” Old ๊ฐ€ ๊ฐ€๋“ ์ฐจ์„œ Promotion ์‹คํŒจ.

์„ธ๋Œ€ ๊ตฌ์กฐ ๋ชจ๋ฅด๋ฉด:

  • ์˜๋ฏธ ํŒŒ์•… ๋ถˆ๊ฐ€

์„ธ๋Œ€ ๊ตฌ์กฐ ์•Œ๋ฉด:

  • "Old๊ฐ€ ๊ฐ€๋“ โ†’ Promotion ์‹คํŒจ โ†’ Full GC ํŠธ๋ฆฌ๊ฑฐ"
  • ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ๋˜๋Š” Heap ๋ถ€์กฑ ๊ฐ€๋Šฅ์„ฑ
  • โ†’ ๋ถ„์„ ๊ฐ€๋Šฅ

์‹œ๋‚˜๋ฆฌ์˜ค 4: ๊ฑฐ๋Œ€ ๊ฐ์ฒด์˜ ์ฒ˜๋ฆฌ

byte[] hugeArray = new byte[100 * 1024 * 1024];  // 100MB

์„ธ๋Œ€ ๊ตฌ์กฐ ๋ชจ๋ฅด๋ฉด:

  • "์–ด๋”” ๊ฐˆ๊นŒ?"

์„ธ๋Œ€ ๊ตฌ์กฐ ์•Œ๋ฉด:

  • Eden์— ์•ˆ ๋“ค์–ด๊ฐ (๋ณดํ†ต Eden ์ˆ˜์‹ญ MB)
  • Humongous Object (G1) ๋˜๋Š” ์ง์ ‘ Old ํ• ๋‹น
  • โ†’ ๋ณ„๋„ ์ฒ˜๋ฆฌ ํ•„์š”

์‹œ๋‚˜๋ฆฌ์˜ค 5: ๋ฉด์ ‘ ๋‹จ๊ณจ ์งˆ๋ฌธ

"๊ฐ์ฒด์˜ ์ผ์ƒ์„ ์„ค๋ช…ํ•ด์ฃผ์„ธ์š”"
"Survivor ๊ฐ€ 2๊ฐœ์ธ ์ด์œ ?"
"Promotion ์ด ๋ญ”๊ฐ€์š”?"

๋‹ต ๋ชปํ•จ:

  • "์Œ... Eden, Survivor, Old ์ •๋„?"
  • โ†’ ์‹œ๋‹ˆ์–ด ์ž๊ฒฉ ์˜์‹ฌ

์ž˜ ๋‹ตํ•จ:

  • ์ •ํ™•ํ•œ ์ผ์ƒ ๋‹จ๊ณ„, Copying GC ์™€ Survivor ์˜ ๊ด€๊ณ„, Tenuring Threshold ๋“ฑ
  • โ†’ ์‹œ๋‹ˆ์–ด ํ›„๋ณด ์ธ์‹

์‹œ๋‚˜๋ฆฌ์˜ค 6: ILIC ์šด์˜ ํ™˜๊ฒฝ ๋ฉ”๋ชจ๋ฆฌ ๋ถ„์„

ILIC ์šด์˜ ํ™˜๊ฒฝ:
- Heap: 4GB
- ํ‰๊ท  ์‘๋‹ต: 50ms
- ๊ฐ€๋” ์‘๋‹ต: 500ms ~ 1s

๋ถ„์„:
GC ๋กœ๊ทธ โ†’ Major GC ๊ฐ€ ๊ฐ€๋” ๋ฐœ์ƒ (200~800ms)

์„ธ๋Œ€ ๊ตฌ์กฐ ๋ชจ๋ฅด๋ฉด:

  • "GC ๊ฐ€ ๋А๋ ค์„œ..." ์ •๋„
  • ํ•ด๊ฒฐ์ฑ… ์—†์Œ

์„ธ๋Œ€ ๊ตฌ์กฐ ์•Œ๋ฉด:

  • Old ์˜์—ญ์— ๊ฐ์ฒด๊ฐ€ ์ฒœ์ฒœํžˆ ์Œ“์ž„
  • Old ๊ฐ€๋“ ์‹œ Major GC + STW
  • โ†’ Heap ๋Š˜๋ฆฌ๊ฑฐ๋‚˜, ZGC ๊ฐ™์€ ์ €์ง€์—ฐ GC ๋„์ž…
  • โ†’ ๊ทผ๋ณธ ํ•ด๊ฒฐ

์„ธ๋Œ€ ๊ตฌ์กฐ ์ดํ•ด์˜ ์ค‘์š”์„ฑ

์‹œ๋‚˜๋ฆฌ์˜ค์„ธ๋Œ€ ๋ชจ๋ฅด๋ฉด์„ธ๋Œ€ ์•Œ๋ฉด
Minor GC ๋นˆ๋„๋ง‰๋ง‰ํ•จEden ํฌ๊ธฐ ์กฐ์ •
Old ๋นจ๋ฆฌ ์ฐธ์›์ธ ๋ชจ๋ฆ„Survivor / Threshold ๋ถ„์„
Promotion Failure๋ฉ”์‹œ์ง€ ๋ชป ์ฝ์Œ์ •ํ™•ํ•œ ์ง„๋‹จ
๊ฑฐ๋Œ€ ๊ฐ์ฒด์ฒ˜๋ฆฌ ๋ชจ๋ฆ„Humongous ์ธ์ง€
๋ฉด์ ‘ํƒˆ๋ฝ์‹œ๋‹ˆ์–ด ์ธ์‹
์šด์˜ ๋ถ„์„ํ‘œ๋ฉด์ ๊ทผ๋ณธ ํ•ด๊ฒฐ

โ†’ ์„ธ๋Œ€ ๊ตฌ์กฐ๋Š” ์ž๋ฐ” ์šด์˜์˜ ํ•„์ˆ˜.


โœ… 4. ํ•ด๊ฒฐ์ฑ… โ€” ์„ธ๋Œ€ ๊ตฌ์กฐ์˜ ์ •ํ™•ํ•œ ์ดํ•ด

Heap ์ „์ฒด ๊ตฌ์กฐ โญ

โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”
โ”‚              Heap                        โ”‚
โ”‚                                          โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
โ”‚  โ”‚     Young Generation (์ž‘์Œ)       โ”‚   โ”‚
โ”‚  โ”‚                                   โ”‚   โ”‚
โ”‚  โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”                   โ”‚   โ”‚
โ”‚  โ”‚  โ”‚   Eden     โ”‚  (๋ณดํ†ต 8/10)      โ”‚   โ”‚
โ”‚  โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜                   โ”‚   โ”‚
โ”‚  โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”  โ”Œโ”€โ”€โ”€โ”€โ”                   โ”‚   โ”‚
โ”‚  โ”‚  โ”‚ S0 โ”‚  โ”‚ S1 โ”‚  (๊ฐ 1/10)        โ”‚   โ”‚
โ”‚  โ”‚  โ””โ”€โ”€โ”€โ”€โ”˜  โ””โ”€โ”€โ”€โ”€โ”˜                   โ”‚   โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
โ”‚                                          โ”‚
โ”‚  โ”Œโ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”   โ”‚
โ”‚  โ”‚     Old Generation (ํผ)            โ”‚   โ”‚
โ”‚  โ”‚     (์žฅ์ˆ˜ ๊ฐ์ฒด)                     โ”‚   โ”‚
โ”‚  โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜   โ”‚
โ””โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”€โ”˜

๊ธฐ๋ณธ ๋น„์œจ (HotSpot JVM):

  • Young : Old = 1 : 2 (Young 1/3)
  • Eden : S0 : S1 = 8 : 1 : 1 (Eden 80%)

JVM ์˜ต์…˜์œผ๋กœ ์กฐ์ •:

-Xms2g -Xmx2g           # ์ „์ฒด Heap 2GB
-Xmn800m                # Young 800MB (๋˜๋Š” -XX:NewSize)
-XX:NewRatio=2          # Young : Old = 1 : 2 (๊ธฐ๋ณธ)
-XX:SurvivorRatio=8     # Eden : S = 8 : 1 (๊ธฐ๋ณธ)

๊ฐ์ฒด์˜ ์ผ์ƒ โญโญโญ (๊ฐ€์žฅ ์ค‘์š”)

๊ฐ์ฒด๊ฐ€ ๋งŒ๋“ค์–ด์ง€๊ณ  ์‚ฌ๋ผ์ง€๋Š” ์ „์ฒด ํ๋ฆ„:

๋‹จ๊ณ„ 1: ์ถœ์ƒ โ€” Eden์— ํ• ๋‹น

Customer alice = new Customer("Alice");
//                โ†‘ Eden ์— ํ• ๋‹น

๋ฉ”๋ชจ๋ฆฌ:

[Eden]
  Customer ("Alice")  โ† ์ƒˆ ๊ฐ์ฒด ์œ„์น˜
[S0] (๋น„์–ด์žˆ์Œ)
[S1] (๋น„์–ด์žˆ์Œ)
[Old] (๋‹ค๋ฅธ ๊ฐ์ฒด๋“ค)

๋‹จ๊ณ„ 2: Eden ๊ฐ€๋“ โ†’ Minor GC

Eden ์ด ๊ฐ€๋“ ์ฐจ๋ฉด Minor GC ํŠธ๋ฆฌ๊ฑฐ:

Minor GC ์‹œ์ž‘:
1. Eden + S0 (๋˜๋Š” S1) ์˜ ์‚ด์•„์žˆ๋Š” ๊ฐ์ฒด ์‹๋ณ„
2. S1 (๋˜๋Š” S0) ์œผ๋กœ ๋ณต์‚ฌ
3. Eden, ์›๋ณธ Survivor ๋น„์›€

์˜ˆ์‹œ:

Before Minor GC:
[Eden] Object A (Live), Object B (Garbage), Object C (Live)
[S0]   (๋น„์–ด์žˆ์Œ)
[S1]   (๋น„์–ด์žˆ์Œ)

After Minor GC:
[Eden] (๋น„์–ด์žˆ์Œ)
[S0]   (๋น„์–ด์žˆ์Œ)
[S1]   Object A (age=1), Object C (age=1)  โ† 1์ฐจ ์ƒ์กด

โ†’ Object B ๋Š” Garbage โ†’ ์‚ฌ๋ผ์ง.


๋‹จ๊ณ„ 3: From โ†” To ์Šค์œ„์นญ

๋‹ค์Œ Minor GC:

Before:
[Eden] Object D, Object E, Object F (๋ชจ๋‘ Live)
[S0]   (๋น„์–ด์žˆ์Œ)
[S1]   Object A (age=1), Object C (age=1)

GC ์ง„ํ–‰:
[Eden + S1] โ†’ S0 ์œผ๋กœ ๋ณต์‚ฌ (๋ฐฉํ–ฅ ๋ฐ”๋€œ!)

After:
[Eden] (๋น„์–ด์žˆ์Œ)
[S0]   Object A (age=2), Object C (age=2), 
       Object D (age=1), Object E (age=1), Object F (age=1)
[S1]   (๋น„์–ด์žˆ์Œ)

ํ•ต์‹ฌ:

  • ์‚ด์•„๋‚จ์€ ๊ฐ์ฒด์˜ age 1 ์ฆ๊ฐ€
  • ํ•ญ์ƒ ํ•œ์ชฝ Survivor๋Š” ๋น„์–ด์žˆ์Œ

๋‹จ๊ณ„ 4: Promotion โ€” Old๋กœ ์ด์ฃผ โญ

๊ฐ์ฒด์˜ age ๊ฐ€ Tenuring Threshold (๊ธฐ๋ณธ 15) ๋„๋‹ฌ:

Object A ๊ฐ€ 15ํšŒ ์‚ด์•„๋‚จ์Œ:
[S0]   Object A (age=15) โ† Threshold ๋„๋‹ฌ!
        โ†“ Promotion
[Old]  Object A
[S0]   ๋น„์›€

Tenuring Threshold:

  • ๊ธฐ๋ณธ๊ฐ’: 15
  • JVM ์˜ต์…˜: -XX:MaxTenuringThreshold=15
  • ๋™์ ์œผ๋กœ ์กฐ์ •๋  ์ˆ˜๋„ ์žˆ์Œ

๋‹จ๊ณ„ 5: Old ๊ฐ€๋“ โ†’ Major GC (Full GC)

Old ์˜์—ญ์ด ๊ฐ€๋“ ์ฐจ๋ฉด:

Major GC (๋˜๋Š” Full GC):
1. Old ์˜ ์‚ด์•„์žˆ๋Š” ๊ฐ์ฒด ์‹๋ณ„
2. Mark-Sweep-Compact ์ง„ํ–‰
3. ๋‹จํŽธํ™” ํ•ด์†Œ

ํšจ๊ณผ:

  • ํฐ STW (์ˆ˜๋ฐฑ ms ~ ์ˆ˜ ์ดˆ)
  • ์‚ฌ์šฉ์ž ์‘๋‹ต ์˜ํ–ฅ
  • โ†’ ์ตœ๋Œ€ํ•œ ํ”ผํ•ด์•ผ ํ•  GC

์ „์ฒด ์ผ์ƒ ๊ทธ๋ฆผ โญ

[ํƒ„์ƒ]
   โ†“
Eden โ”€โ”€Minor GCโ”€โ”€โ†’ Survivor (age 1)
                       โ†“ Minor GC
                   Survivor (age 2)
                       โ†“ ... (15ํšŒ)
                       โ†“
                       โ””โ”€โ”€Promotionโ”€โ”€โ†’ Old
                                          โ†“ Major GC
                                       (์ˆ˜๊ฑฐ)

3๊ฐ€์ง€ GC ๋น„๊ต โญโญ (๋ฉด์ ‘ ๋‹จ๊ณจ)

Minor GC

๋Œ€์ƒ: Young Generation (Eden + Survivor)

๋นˆ๋„: ์ž์ฃผ (์ˆ˜ ์ดˆ๋งˆ๋‹ค)

์‹œ๊ฐ„: ๋น ๋ฆ„ (๋ณดํ†ต ~10ms)

STW: ์งง์Œ

์•Œ๊ณ ๋ฆฌ์ฆ˜: Copying GC

๊ด€์ฐฐ ๊ฐ€๋Šฅ:

GC(0) Pause Young 25M->2M(64M) 5ms

Major GC

๋Œ€์ƒ: Old Generation ๋งŒ

๋นˆ๋„: ๊ฐ€๋” (๋ถ„~์‹œ๊ฐ„ ๋‹จ์œ„)

์‹œ๊ฐ„: ๋А๋ฆผ (์ˆ˜๋ฐฑ ms ~ ์ˆ˜ ์ดˆ)

STW: ๊น€ (๋˜๋Š” Concurrent)

์•Œ๊ณ ๋ฆฌ์ฆ˜: Mark-Sweep-Compact (๋˜๋Š” Concurrent)

๊ด€์ฐฐ ๊ฐ€๋Šฅ:

GC(50) Pause Old 100M->80M(150M) 500ms

Full GC

๋Œ€์ƒ: Heap ์ „์ฒด (Young + Old + Metaspace)

๋นˆ๋„: ๋งค์šฐ ๊ฐ€๋” (๋˜๋Š” ์˜๋„์  ํŠธ๋ฆฌ๊ฑฐ)

์‹œ๊ฐ„: ๋งค์šฐ ๋А๋ฆผ (์ดˆ ๋‹จ์œ„)

STW: ๋งค์šฐ ๊น€

์›์ธ:

  • Old ๊ฐ€๋“ + Promotion ์‹คํŒจ
  • System.gc() ํ˜ธ์ถœ
  • Metaspace ๋ถ€์กฑ

๊ฒฝ๊ณ : Full GC ๊ฐ€ ์ž์ฃผ ๋ฐœ์ƒ = ๋ฉ”๋ชจ๋ฆฌ ๋ฌธ์ œ โš ๏ธ


๋น„๊ต ํ‘œ โญ

Minor GCMajor GCFull GC
๋Œ€์ƒYoungOld์ „์ฒด
๋นˆ๋„์ž์ฃผ๊ฐ€๋”๋งค์šฐ ๊ฐ€๋”
์‹œ๊ฐ„๋น ๋ฆ„ (~ms)๋А๋ฆผ (~์ˆ˜๋ฐฑ ms)๋งค์šฐ ๋А๋ฆผ (~์ดˆ)
STW์งง์Œ๊น€๋งค์šฐ ๊น€
์•Œ๊ณ ๋ฆฌ์ฆ˜CopyingMark-Sweep-Compact๋‹ค์–‘
๋ฐœ์ƒ ํŠธ๋ฆฌ๊ฑฐEden ๊ฐ€๋“Old ๊ฐ€๋“๋‹ค์–‘

Survivor๊ฐ€ 2๊ฐœ์ธ ์ด์œ  โญ (์ž๊ธฐ ์ ๊ฒ€ Q1)

1๊ฐœ๋ผ๋ฉด?:

  • Survivor ์•ˆ์—์„œ ์ž์ฒด GC ์–ด๋ ค์›€
  • ๋‹จํŽธํ™” ๋ฐœ์ƒ

2๊ฐœ๋กœ ์šด์˜:

  • ํ•œ์ชฝ์€ ํ•ญ์ƒ ๋น„์–ด์žˆ์Œ (To)
  • ๋‹ค๋ฅธ ์ชฝ์ด ํ˜„์žฌ ์‚ฌ์šฉ (From)
  • Minor GC ์‹œ [Eden + From] โ†’ [To]
  • ๋‹ค์Œ์—๋Š” ์—ญํ•  ๋ฐ”๋€œ

ํšจ๊ณผ:

  • ์ž๋™ ์••์ถ• (Copying GC)
  • ๋‹จํŽธํ™” ์—†์Œ
  • ๊ฐ„๋‹จํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜

โ†’ Q1 ๋‹ต: Copying GC ํ™œ์šฉ + ๋‹จํŽธํ™” ์ž๋™ ํ•ด์†Œ.


๊ฑฐ๋Œ€ ๊ฐ์ฒด ์ฒ˜๋ฆฌ โญ (์ž๊ธฐ ์ ๊ฒ€ Q2)

๊ฑฐ๋Œ€ ๊ฐ์ฒด = Survivor ์˜์—ญ๋ณด๋‹ค ํฐ ๊ฐ์ฒด.

๋ฌธ์ œ:

  • Survivor ์— ์•ˆ ๋“ค์–ด๊ฐ
  • ๋งค Minor GC ๋งˆ๋‹ค ๋ณต์‚ฌ ๋น„์šฉ ํผ

ํ•ด๊ฒฐ:

1. ์ง์ ‘ Old ํ• ๋‹น

  • ํฐ ๊ฐ์ฒด๋Š” Eden ๋„ ๊ฑฐ์น˜์ง€ ์•Š๊ณ  ๋ฐ”๋กœ Old ๋กœ
  • JVM ์˜ต์…˜: -XX:PretenureSizeThreshold=N

2. G1 ์˜ Humongous Object

  • G1 GC ๋Š” Region ๊ธฐ๋ฐ˜
  • Region ์˜ ์ ˆ๋ฐ˜ ์ด์ƒ ์ฐจ์ง€ํ•˜๋ฉด Humongous
  • ๋ณ„๋„ ์˜์—ญ์—์„œ ๊ด€๋ฆฌ
[G1 Heap]
  โ”œโ”€โ”€ Eden Region
  โ”œโ”€โ”€ Survivor Region
  โ”œโ”€โ”€ Old Region
  โ””โ”€โ”€ Humongous Region  โ† ํฐ ๊ฐ์ฒด

โ†’ Q2 ๋‹ต: ์ง์ ‘ Old ํ• ๋‹น ๋˜๋Š” Humongous ์˜์—ญ.


๐Ÿ—๏ธ 5. ๋‚ด๋ถ€ ๋™์ž‘ ์›๋ฆฌ

Minor GC ์˜ ์ž์„ธํ•œ ํ๋ฆ„

// ์‹œ์ž‘ ์ƒํƒœ:
// Eden:  [A][B][C][D][E]  (๋ชจ๋‘ ์ƒˆ ๊ฐ์ฒด, B๋Š” Garbage)
// S0:    (๋น„์–ด์žˆ์Œ)
// S1:    (๋น„์–ด์žˆ์Œ)
// Old:   [oldX][oldY]

Step 1: GC ํŠธ๋ฆฌ๊ฑฐ

  • Eden ๊ฐ€๋“ โ†’ Minor GC ์‹œ์ž‘
  • STW ์‹œ์ž‘

Step 2: GC Root ์‹๋ณ„

  • Stack ์˜ ์ง€์—ญ๋ณ€์ˆ˜
  • Old ์˜ ๊ฐ์ฒด (Card Table ์˜ dirty ์นด๋“œ)
  • static ํ•„๋“œ

Step 3: ๋งˆํ‚น (Reachability ๋ถ„์„)

  • Live: A, C, D, E
  • Garbage: B

Step 4: Copying โ€” ์‚ด์•„์žˆ๋Š” ๊ฐ์ฒด๋ฅผ S1 ๋กœ

After:
Eden: (๋น„์–ด์žˆ์Œ)
S0:   (๋น„์–ด์žˆ์Œ)
S1:   [A age=1][C age=1][D age=1][E age=1]
Old:  [oldX][oldY]

Step 5: STW ์ข…๋ฃŒ

  • Application Thread ์žฌ๊ฐœ

Step 6: ๋‹ค์Œ GC

  • Eden ๋‹ค์‹œ ๊ฐ€๋“ ์ฐจ๋ฉด
  • ์ด๋ฒˆ์—” [Eden + S1] โ†’ S0
  • ๋งค๋ฒˆ ๋ฐฉํ–ฅ์ด ๋ฐ”๋€œ

Promotion์˜ ์ •ํ™•ํ•œ ๋ฉ”์ปค๋‹ˆ์ฆ˜ โญ

// Object A: age=14
// Tenuring Threshold = 15

// Minor GC ๋ฐœ์ƒ:
// A ๊ฐ€ ์‚ด์•„๋‚จ์Œ โ†’ age=15
// โ†’ Threshold ๋„๋‹ฌ!
// โ†’ Old ๋กœ Promotion

[Survivor]
  [A age=15] โ†’ ์‚ฌ๋ผ์ง
[Old]
  [oldX][oldY][A] โ† ์ƒˆ๋กœ ๋“ค์–ด์˜ด

Adaptive Tenuring:

  • JVM ์ด Survivor ์‚ฌ์šฉ๋Ÿ‰์„ ๋ณด๊ณ  ๋™์  ์กฐ์ •
  • Survivor ๊ฐ€ 50% ๋„˜์œผ๋ฉด Threshold ๋‚ฎ์ถค
  • โ†’ ๋น ๋ฅธ Promotion
# ์กฐ์ • ์˜ต์…˜
-XX:MaxTenuringThreshold=15        # ์ตœ๋Œ€ 15ํšŒ
-XX:TargetSurvivorRatio=50         # Survivor ๋ชฉํ‘œ 50%

Card Table์˜ ๋™์ž‘ โญ (์žฌํ™•์ธ)

๋ฌธ์ œ: Old โ†’ Young ์ฐธ์กฐ๊ฐ€ ์žˆ์œผ๋ฉด Minor GC ์‹œ Old ๋„ ๋ด์•ผ ํ•จ.

์˜ˆ์‹œ:

public class FareCache {
    private static List<Fare> cache = new ArrayList<>();  // Old (long-lived)
    
    public void add(Fare fare) {  // fare ๋Š” Young
        cache.add(fare);
        // Old ๊ฐ์ฒด cache ๊ฐ€ Young ๊ฐ์ฒด fare ์ฐธ์กฐ
    }
}

Card Table:

  • Old ์˜์—ญ์„ 512 byte ์นด๋“œ ๋กœ ๋‚˜๋ˆ”
  • 1GB Old โ†’ ์•ฝ 200๋งŒ ์นด๋“œ
  • ๊ฐ ์นด๋“œ 1 byte โ†’ 2MB Card Table

dirty ๋งˆํ‚น:

// cache.add(fare) ์‹คํ–‰ ์‹œ โ€” Write Barrier ๋ฐœ์ƒ
//   (JVM ์ด ์ž๋™ ์ฒ˜๋ฆฌ)

// JVM:
// "cache ๊ฐ์ฒด๊ฐ€ fare (Young) ์ฐธ์กฐ ์ถ”๊ฐ€"
// โ†’ cache ๊ฐ€ ์žˆ๋Š” ์นด๋“œ๋ฅผ dirty ๋งˆํ‚น

Minor GC ์‹œ:
1. Stack, static ์˜ GC Root ์Šค์บ”
2. dirty ์นด๋“œ๋งŒ Old ์—์„œ ์ถ”๊ฐ€ ์Šค์บ”
3. ๋ชจ๋“  Live ๊ฐ์ฒด ๋งˆํ‚น

ํšจ๊ณผ:

  • Old ์ „์ฒด (์ˆ˜ GB) ์Šค์บ” ํšŒํ”ผ
  • dirty ์นด๋“œ๋งŒ (์ˆ˜ MB) ์Šค์บ”
  • โ†’ Minor GC ๋น ๋ฆ„ ์œ ์ง€

Write Barrier โญ

Write Barrier = ๊ฐ์ฒด ์ฐธ์กฐ ๋ณ€๊ฒฝ ์‹œ JVM ์ด ์ž๋™ ์‹คํ–‰ํ•˜๋Š” ์ฝ”๋“œ.

์—ญํ• :

  • Old โ†’ Young ์ฐธ์กฐ ๋ฐœ์ƒ ์‹œ Card Table dirty ๋งˆํ‚น
  • G1 ์˜ Region ๊ฐ„ ์ฐธ์กฐ ์ถ”์ 
  • Concurrent GC์˜ ์ผ๊ด€์„ฑ ์œ ์ง€

๋น„์šฉ:

  • ๋งค ์ฐธ์กฐ ๋ณ€๊ฒฝ๋งˆ๋‹ค ์•ฝ๊ฐ„์˜ ์˜ค๋ฒ„ํ—ค๋“œ
  • ๊ทธ๋Ÿฌ๋‚˜ Card Table ์˜ ํšจ๊ณผ๋กœ ์ถฉ๋ถ„ํžˆ ๊ฐ€์น˜

์˜์—ญ๋ณ„ ๊ฐ์ฒด ์ˆ˜ ํŒจํ„ด

์ „ํ˜•์ ์ธ ์ž๋ฐ” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜:

Eden:  ๋งค์šฐ ๋งŽ์€ ๊ฐ์ฒด (์ˆ˜๋งŒ~์ˆ˜์‹ญ๋งŒ)
       ๋Œ€๋ถ€๋ถ„ ๊ณง Garbage

S0/S1: ์ ์€ ๊ฐ์ฒด (์ˆ˜๋ฐฑ~์ˆ˜์ฒœ)
       Eden ์˜ 1~10%

Old:   ์ ๋‹นํ•œ ๊ฐ์ฒด (์ˆ˜์ฒœ~์ˆ˜๋งŒ)
       ์‚ด์•„๋‚จ์€ ๊ฒƒ๋“ค

๊ฐ์ฒด ์ˆ˜์˜ ๋ถ„ํฌ:

  • Eden: 80%
  • Survivor: 5%
  • Old: 15%

โ†’ ์•ฝํ•œ ์„ธ๋Œ€ ๊ฐ€์„ค ์˜ ์‹ค์ œ ๋ชจ์Šต.


Region-Based Heap (G1 GC)

๊ธฐ์กด ์„ธ๋Œ€ ๊ตฌ์กฐ์˜ ์ง„ํ™” โ€” G1 GC ๋Š” Region ๊ธฐ๋ฐ˜:

[Heap]
โ”œโ”€โ”€ Region 0 (Eden)
โ”œโ”€โ”€ Region 1 (Eden)
โ”œโ”€โ”€ Region 2 (Survivor)
โ”œโ”€โ”€ Region 3 (Old)
โ”œโ”€โ”€ Region 4 (Humongous)
โ”œโ”€โ”€ Region 5 (Free)
โ”œโ”€โ”€ Region 6 (Eden)
โ”œโ”€โ”€ Region 7 (Old)
โ””โ”€โ”€ ... (์ˆ˜๋ฐฑ ๊ฐœ Region)

ํŠน์ง•:

  • Region ๋งˆ๋‹ค ์—ญํ•  ๋™์  ๋ณ€๊ฒฝ
  • ์ˆ˜๋ฐฑ ๊ฐœ Region ์œผ๋กœ ๋ถ„ํ•  (๋ณดํ†ต 1~32MB)
  • Garbage๊ฐ€ ๋งŽ์€ Region ๋ถ€ํ„ฐ GC
  • โ†’ ๋” ํšจ์œจ์ ์ธ ๋ฉ”๋ชจ๋ฆฌ ํ™œ์šฉ

โ†’ Unit 5.4 ์—์„œ ์ž์„ธํžˆ.


๐Ÿ’ป 6. ์‹ค์ „ ์ฝ”๋“œ ์˜ˆ์‹œ

์˜ˆ์‹œ 1: ๊ฐ์ฒด์˜ ์ผ์ƒ ๊ด€์ฐฐ

public class GenerationDemo {
    public static void main(String[] args) {
        Runtime runtime = Runtime.getRuntime();
        
        for (int i = 0; i < 1000; i++) {
            // ์ƒˆ ๊ฐ์ฒด โ€” Eden ์—
            byte[] data = new byte[1024 * 100];  // 100KB
            
            if (i % 100 == 0) {
                System.out.printf("Iteration %d, Free memory: %d MB%n",
                    i, runtime.freeMemory() / (1024 * 1024));
            }
            
            // i % 100 == 0 ์ผ ๋•Œ๋งŒ ์‚ด๋ ค๋‘  (๋‹ค๋ฅธ ์ปฌ๋ ‰์…˜์— ์ฐธ์กฐ)
            if (i % 100 == 0) {
                staticList.add(data);  // Old ๋กœ ๊ฐ€๊ฒŒ ๋งŒ๋“ฆ
            }
        }
    }
    
    private static List<byte[]> staticList = new ArrayList<>();  // GC Root
}

JVM ์˜ต์…˜ ์ถ”๊ฐ€:

java -Xmx256m -Xms256m \
     -Xlog:gc*:stdout:time,uptime,level,tags \
     GenerationDemo

๊ด€์ฐฐ:

  • Minor GC ์ž์ฃผ ๋ฐœ์ƒ (Eden ๊ฐ€๋“)
  • ์ผ๋ถ€ ๊ฐ์ฒด๋Š” Survivor โ†’ Old ์ด๋™
  • ์šด์˜ ์‹œ Old ๊ฐ€ ์ ์  ์ฐจ๋Š” ๋ชจ์Šต

์˜ˆ์‹œ 2: GC ๋กœ๊ทธ ๋ถ„์„

java -Xms512m -Xmx512m \
     -Xlog:gc*:file=gc.log:time,uptime,level,tags \
     YourApp

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

[0.150s] GC(0) Pause Young (G1 Evacuation Pause)
         15M->5M(512M) 8.123ms
         
[1.234s] GC(1) Pause Young (G1 Evacuation Pause)
         15M->6M(512M) 7.456ms

[5.678s] GC(2) Pause Young (G1 Mixed GC)  โ† Old๋„ ์ผ๋ถ€ GC
         50M->10M(512M) 25.123ms

[60.123s] GC(3) Pause Full (Allocation Failure)
          200M->50M(512M) 350.456ms  โ† Full GC! โš ๏ธ

ํ•ด์„:

  • Minor GC: ๋น ๋ฆ„ (~10ms)
  • Mixed GC: G1์˜ Young + Old ๋ถ€๋ถ„
  • Full GC: ์œ„ํ—˜ ์‹ ํ˜ธ โ€” ๋ถ„์„ ํ•„์š”

์˜ˆ์‹œ 3: ILIC ์šด์ž„ ์ฒ˜๋ฆฌ์˜ GC ์˜ํ–ฅ

@Service
public class FareReportService {
    
    // โŒ ๋ฉ”๋ชจ๋ฆฌ ํญ๋ฐœ ๊ฐ€๋Šฅ
    public byte[] generateAllFaresReport() {
        List<Fare> all = repository.findAll();  // 100๋งŒ ๊ฑด?
        // โ†’ Eden ํญ๋ฐœ โ†’ Survivor ๊ฑฐ์ณ Old ๊นŒ์ง€
        // โ†’ Heap ๊ฐ€๋“ โ†’ OOM ๋˜๋Š” Full GC
        
        return generatePdf(all);
    }
    
    // โœ… Streaming
    public void generateReportStream(OutputStream out) {
        try (Stream<Fare> stream = repository.findAllAsStream()) {
            stream.forEach(fare -> {
                appendToPdf(out, fare);
                // fare ๋Š” ์‚ฌ์šฉ ํ›„ Eden ์˜ Garbage ๊ฐ€ ๋จ
                // โ†’ Minor GC ๋กœ ๋น ๋ฅด๊ฒŒ ํšŒ์ˆ˜
            });
        }
        // ๋ฉ”๋ชจ๋ฆฌ ์†Œ๋น„ ๊ฑฐ์˜ ์—†์Œ
    }
}

GC ์ธก๋ฉด:

  • Streaming โ†’ ๊ฑฐ์˜ ๋ชจ๋“  ๊ฐ์ฒด๊ฐ€ Young ์—์„œ ์ฃฝ์Œ
  • ์•ฝํ•œ ์„ธ๋Œ€ ๊ฐ€์„ค์˜ ๋ชจ๋ฒ” ์‚ฌ๋ก€
  • Minor GC ๋งŒ์œผ๋กœ ์ฒ˜๋ฆฌ

์˜ˆ์‹œ 4: Promotion ๋น ๋ฅด๊ฒŒ โ€” ์œ„ํ—˜ ํŒจํ„ด

@Component
public class FareCache {
    private final Map<Long, Fare> cache = new ConcurrentHashMap<>();
    
    @Scheduled(fixedRate = 1000)  // 1์ดˆ๋งˆ๋‹ค
    public void refresh() {
        List<Fare> recent = repository.findRecent();
        recent.forEach(f -> cache.put(f.getId(), f));
        // โš ๏ธ Fare ๋“ค์ด ๊ณง๋ฐ”๋กœ Old ๋กœ Promotion
        // โ†’ cache ๊ฐ€ GC Root ์ด๊ธฐ ๋•Œ๋ฌธ
        // โ†’ Old ์˜์—ญ ๋น ๋ฅด๊ฒŒ ์ฐธ
        // โ†’ Major GC ๋นˆ๋ฒˆ
    }
}

๋ฌธ์ œ:

  • cache ๋Š” long-lived (Spring Bean)
  • cache.put() โ†’ fare ๊ฐ€ cache ์—์„œ ์ฐธ์กฐ๋จ
  • โ†’ fare ๊ฐ€ Survivor ๊ฑฐ์ณ Old ๋กœ
  • โ†’ Old ์˜์—ญ ์••๋ฐ•

๊ฐœ์„ :

@Component
public class FareCache {
    private final Cache<Long, Fare> cache = 
        Caffeine.newBuilder()
            .expireAfterWrite(Duration.ofMinutes(5))  // ๋งŒ๋ฃŒ
            .maximumSize(1000)                          // ํฌ๊ธฐ ์ œํ•œ
            .build();
    // โ†’ ์ ์ ˆํ•œ ํฌ๊ธฐ ์œ ์ง€
    // โ†’ Old ์˜์—ญ ์•ˆ์ •
}

์˜ˆ์‹œ 5: Survivor ํฌ๊ธฐ ๋ชจ๋‹ˆํ„ฐ๋ง

# JVM ์˜ต์…˜
java -XX:+PrintTenuringDistribution \
     -Xlog:gc*:stdout \
     YourApp

์ถœ๋ ฅ:

Desired survivor size 524288 bytes, new threshold 7 (max 15)
- age 1:    245664 bytes,    245664 total
- age 2:    156784 bytes,    402448 total
- age 3:     89456 bytes,    491904 total
- age 4:     45120 bytes,    537024 total  โ† ์ดˆ๊ณผ!

ํ•ด์„:

  • "Desired survivor size 512KB"
  • age 4 ๊นŒ์ง€ ๋ˆ„์  537KB โ†’ ์ดˆ๊ณผ
  • โ†’ Adaptive Tenuring ์œผ๋กœ Threshold ๋‚ฎ์•„์ง (15 โ†’ 7)
  • โ†’ ๋น ๋ฅธ Promotion

โ†’ Old ์˜์—ญ ์••๋ฐ• ์‹ ํ˜ธ.


์˜ˆ์‹œ 6: ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ํŒจํ„ด

// โŒ static ์ปฌ๋ ‰์…˜ โ€” Old ์— ๋ฌดํ•œ ๋ˆ„์ 
public class FareLogger {
    private static List<String> logs = new ArrayList<>();
    
    public static void log(String message) {
        logs.add(LocalDateTime.now() + " - " + message);
        // logs ๊ฐ€ ๋ฌดํ•œ ์ฆ๊ฐ€
    }
}

GC ๊ด€์ ์—์„œ์˜ ๋ฌธ์ œ:

  • logs ๋Š” static โ†’ GC Root
  • ์ถ”๊ฐ€๋œ String ๋“ค์ด Old ๋กœ ๊ณ„์† Promotion
  • โ†’ Old ๊ฐ€๋“ โ†’ Full GC ์‹œ๋„
  • โ†’ ๊ทธ๋Ÿฌ๋‚˜ logs ์ž์ฒด๊ฐ€ Live โ†’ ํšŒ์ˆ˜ ๋ถˆ๊ฐ€
  • โ†’ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜

ํ•ด๊ฒฐ:

public class FareLogger {
    private static final int MAX_SIZE = 1000;
    private static final Deque<String> logs = new ArrayDeque<>(MAX_SIZE);
    
    public static synchronized void log(String message) {
        if (logs.size() >= MAX_SIZE) {
            logs.pollFirst();  // ์˜ค๋ž˜๋œ ๊ฒƒ ์ œ๊ฑฐ
        }
        logs.addLast(LocalDateTime.now() + " - " + message);
    }
}

์˜ˆ์‹œ 7: ILIC ์˜ GC ์นœํ™”์  ํŒจํ„ด

@Service
public class FareCalculator {
    
    // โœ… ์งง์€ ์ผ์ƒ์˜ ๊ฐ์ฒด๋งŒ
    public Money calculate(Fare fare, Customer customer) {
        // ๋ชจ๋‘ ๋ฉ”์„œ๋“œ ์•ˆ์—์„œ๋งŒ ์‚ฌ์šฉ โ†’ Eden ์—์„œ ์ฃฝ์Œ
        Money base = Money.of(fare.getAmount());
        Money discount = base.multiply(customer.getDiscountRate())
                              .divide(100);
        Money tax = base.subtract(discount).multiply(0.1);
        return base.subtract(discount).add(tax);
    }
}

GC ํŒจํ„ด:

  • Money ๊ฐ์ฒด๋“ค์ด ์ฆ‰์‹œ ์‚ฌ์šฉ ํ›„ ๋ฒ„๋ ค์ง
  • Eden โ†’ Survivor ๋„ ์•ˆ ๊ฐ€๊ณ  ๊ณง๋ฐ”๋กœ Garbage
  • Minor GC ๋กœ ๋น ๋ฅธ ํšŒ์ˆ˜
  • Old ์˜์—ญ ์˜ํ–ฅ X

โ†’ ์•ฝํ•œ ์„ธ๋Œ€ ๊ฐ€์„ค ์˜ ๋ชจ๋ฒ” ์‚ฌ๋ก€.


โš ๏ธ 7. ์ฃผ์˜์‚ฌํ•ญ & ํ”ํ•œ ์‹ค์ˆ˜

์‹ค์ˆ˜ 1: "Eden ๋งŒ ์•Œ๊ณ  Survivor ๋ชจ๋ฆ„"

Q: "๊ฐ์ฒด์˜ ์ผ์ƒ?"
A: "Eden โ†’ Old ์ž…๋‹ˆ๋‹ค" โŒ

์ •๋‹ต: Eden โ†’ Survivor (์—ฌ๋Ÿฌ ํšŒ) โ†’ Old

Survivor ๋Š” ํ•„ํ„ฐ๋ง ์—ญํ• . ์ง„์งœ ์žฅ์ˆ˜ ๊ฐ์ฒด๋งŒ Old ๋กœ.


์‹ค์ˆ˜ 2: "Survivor ๊ฐ€ 1๊ฐœ"

Q: "Survivor ๊ฐ€ ๋ช‡ ๊ฐœ?"
A: "1๊ฐœ์š”" โŒ

์ •๋‹ต: 2๊ฐœ (S0, S1 ๋˜๋Š” From, To)

Copying GC ์œ„ํ•ด ๋‘˜์ด ๋ฒˆ๊ฐˆ์•„ ์‚ฌ์šฉ.


์‹ค์ˆ˜ 3: Major GC ์™€ Full GC ํ˜ผ๋™

Q: "Major GC ์™€ Full GC ์ฐจ์ด?"
A: "๊ฐ™์€ ๊ฑฐ ์•„๋‹Œ๊ฐ€์š”?" โŒ

์ •๋‹ต:

  • Major GC: Old ๋งŒ
  • Full GC: ์ „์ฒด (Young + Old + Metaspace)

์ž์ฃผ ํ˜ผ์šฉ๋˜์ง€๋งŒ ์—„๋ฐ€ํžˆ๋Š” ๋‹ค๋ฆ„.


์‹ค์ˆ˜ 4: Tenuring Threshold ๊ฐ€ ํ•ญ์ƒ 15

Q: "๊ฐ์ฒด๊ฐ€ Old ๋กœ ๊ฐ€๋Š” ์กฐ๊ฑด?"
A: "15ํšŒ ์‚ด์•„๋‚จ์œผ๋ฉด" โŒ (๋ถ€์ •ํ™•)

์ •๋‹ต:

  • MaxTenuringThreshold = 15 (๊ธฐ๋ณธ)
  • ๊ทธ๋Ÿฌ๋‚˜ Adaptive Tenuring ์œผ๋กœ ๋™์  ์กฐ์ •
  • Survivor ๊ฐ€ ๊ฐ€๋“ ์ฐจ๋ฉด Threshold ๋‚ฎ์•„์ง
  • 7~15 ๋ฒ”์œ„์—์„œ ๋ณ€๋™

์‹ค์ˆ˜ 5: "Eden ์— ๋ฌดํ•œ ๊ฐ์ฒด ๋งŒ๋“ค ์ˆ˜ ์žˆ์Œ"

for (int i = 0; i < Integer.MAX_VALUE; i++) {
    Fare fare = new Fare();
    fares.add(fare);  // โš ๏ธ ๋ˆ„์ 
}

๋ฌธ์ œ:

  • fares ๊ฐ€ ์‚ด์•„์žˆ์–ด fare ๋“ค์ด Old ๋กœ Promotion
  • Old ๊ฐ€๋“ โ†’ Full GC โ†’ OOM

ํ•ด๊ฒฐ: ์ฒ˜๋ฆฌ ํ›„ ์ฐธ์กฐ ๋Š๊ธฐ, Stream ์‚ฌ์šฉ ๋“ฑ.


์‹ค์ˆ˜ 6: Survivor ํฌ๊ธฐ ๋ฌด์‹œ

java -Xmx2g -XX:NewSize=1g  # Young 1GB
                              # ๊ทธ๋Ÿฐ๋ฐ SurvivorRatio ๋Š” ๊ธฐ๋ณธ 8
                              # โ†’ Eden 800MB, S0/S1 ๊ฐ 100MB

๊ฐ€๋Šฅํ•œ ๋ฌธ์ œ:

  • Survivor 100MB ๊ฐ€ ๋ถ€์กฑํ•  ์ˆ˜ ์žˆ์Œ
  • โ†’ ๋น ๋ฅธ Promotion โ†’ Old ์••๋ฐ•

ํŠœ๋‹ ์‹œ ๊ณ ๋ ค:

-XX:SurvivorRatio=8  # Eden:S0:S1 = 8:1:1 (๊ธฐ๋ณธ)
-XX:SurvivorRatio=4  # Eden:S0:S1 = 4:1:1 (Survivor ๋” ํผ)

์‹ค์ˆ˜ 7: Full GC ๊ฐ€ ์ •์ƒ์ด๋ผ๊ณ  ์ƒ๊ฐ

์šด์˜: Full GC ๊ฐ€ ๋งค ๋ถ„๋งˆ๋‹ค ๋ฐœ์ƒ
๊ฐœ๋ฐœ์ž: "GC ์ž˜ ๋Œ๊ณ  ์žˆ๋„ค"

์ง„์‹ค: Full GC ๋Š” ์œ„ํ—˜ ์‹ ํ˜ธ โš ๏ธ

์ •์ƒ:

  • Minor GC: ์ž์ฃผ (์ˆ˜ ์ดˆ๋งˆ๋‹ค OK)
  • Major GC: ๊ฐ€๋” (๋ถ„~์‹œ๊ฐ„)
  • Full GC: ๋งค์šฐ ๊ฐ€๋” (์‹œ๊ฐ„~์ผ ๋‹จ์œ„)

๋งค ๋ถ„ Full GC = ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ๊ฐ€๋Šฅ์„ฑ ๋†’์Œ.


๐Ÿ”— 8. ์—ฐ๊ด€ ๊ฐœ๋… ๋งต

Phase 5 (GC) ๋‚ด ํ๋ฆ„

[Unit 5.1: GC ๊ธฐ๋ณธ + ์•ฝํ•œ ์„ธ๋Œ€ ๊ฐ€์„ค] โœ“
        โ†“
[Unit 5.2: Heap ์˜ ์„ธ๋Œ€ ๊ตฌ์กฐ] โ† ์ง€๊ธˆ ์—ฌ๊ธฐ โ˜…
        โ†“
[Unit 5.3: GC ์•Œ๊ณ ๋ฆฌ์ฆ˜ 4๊ฐ€์ง€]
        โ†“
[Unit 5.4: GC ์ข…๋ฅ˜์™€ ์„ ํƒ ๊ธฐ์ค€]

Phase 4 ์™€์˜ ํ†ตํ•ฉ

ํ•™์Šต์„ธ๋Œ€ ๊ตฌ์กฐ ๊ด€์ 
Unit 4.1 (Heap)์„ธ๋Œ€ ๊ตฌ์กฐ์˜ ๋ฌด๋Œ€
Unit 4.2 (Pass by Value)๊ฐ์ฒด ์ฐธ์กฐ โ†’ ์„ธ๋Œ€ ์ถ”์ 
Unit 5.1 (์•ฝํ•œ ์„ธ๋Œ€ ๊ฐ€์„ค)์„ธ๋Œ€ ๊ตฌ์กฐ์˜ ์ด์œ 

โ†’ Phase 4-5 ๊ฐ€ ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ์—ฐ๊ฒฐ.


๋ฏธ๋ž˜ ์ฃผ์ฐจ์™€์˜ ์—ฐ๊ฒฐ

5์ฃผ์ฐจ (Spring DI):

  • Bean ์˜ Singleton โ†’ Old Generation
  • Prototype โ†’ Young ๋˜๋Š” Old

11-12์ฃผ์ฐจ (JPA):

  • ์˜์†์„ฑ ์ปจํ…์ŠคํŠธ โ†’ Old (ํŠธ๋žœ์žญ์…˜ ๋‚ด)
  • 1์ฐจ ์บ์‹œ โ†’ ํŠธ๋žœ์žญ์…˜ ์ข…๋ฃŒ ์‹œ GC

13-14์ฃผ์ฐจ (DB/Cache):

  • Redis vs JVM ์บ์‹œ โ€” Heap ์˜ํ–ฅ ์ฐจ์ด
  • Caffeine ๊ฐ™์€ ๋งŒ๋ฃŒ ์บ์‹œ

4์ฃผ์ฐจ (๋™์‹œ์„ฑ):

  • ๋ฉ€ํ‹ฐ์Šค๋ ˆ๋“œ + GC ์˜ ์ƒํ˜ธ์ž‘์šฉ

JVM ์˜ต์…˜ (ํŠœ๋‹ ์‹œ ์‚ฌ์šฉ) โญ

# Heap ํฌ๊ธฐ
-Xms2g -Xmx2g                     # ์ดˆ๊ธฐ/์ตœ๋Œ€ Heap

# Young ํฌ๊ธฐ
-Xmn800m                          # Young 800MB
-XX:NewRatio=2                    # Young : Old = 1 : 2
-XX:NewSize=400m                  # Young ์ดˆ๊ธฐ
-XX:MaxNewSize=800m               # Young ์ตœ๋Œ€

# Survivor ๋น„์œจ
-XX:SurvivorRatio=8               # Eden : S = 8 : 1 (๊ธฐ๋ณธ)

# Promotion
-XX:MaxTenuringThreshold=15       # ์ตœ๋Œ€ 15ํšŒ
-XX:TargetSurvivorRatio=50        # Survivor ๋ชฉํ‘œ 50%

# ๊ฑฐ๋Œ€ ๊ฐ์ฒด
-XX:PretenureSizeThreshold=1m     # 1MB ์ด์ƒ์€ ์ง์ ‘ Old

# ๋ชจ๋‹ˆํ„ฐ๋ง
-XX:+PrintTenuringDistribution    # ์„ธ๋Œ€๋ณ„ ๋ถ„ํฌ ์ถœ๋ ฅ
-Xlog:gc*                         # GC ๋กœ๊ทธ

๋ฉด์ ‘ ๋‹จ๊ณจ ์งˆ๋ฌธ ๋งคํ•‘

์งˆ๋ฌธ์ด Unit์—์„œ์˜ ๋‹ต
"๊ฐ์ฒด์˜ ์ผ์ƒ?"Eden โ†’ Survivor (15ํšŒ) โ†’ Old
"Survivor ๊ฐ€ 2๊ฐœ์ธ ์ด์œ ?"Copying GC + ๋‹จํŽธํ™” ํ•ด์†Œ
"Minor vs Major vs Full GC?"๋Œ€์ƒ ์˜์—ญ๊ณผ ๋นˆ๋„/์‹œ๊ฐ„ ์ฐจ์ด
"Promotion ์ด ๋ญ”๊ฐ€์š”?"Tenuring Threshold ๋„๋‹ฌ ์‹œ Old ์ด๋™
"๊ฑฐ๋Œ€ ๊ฐ์ฒด ์ฒ˜๋ฆฌ?"์ง์ ‘ Old ๋˜๋Š” Humongous (G1)
"Card Table?"Old โ†’ Young ์ฐธ์กฐ ์ถ”์ 

๐Ÿ“ 9. ํ•ต์‹ฌ ์š”์•ฝ โ€” 3์ค„ ์ •๋ฆฌ

1๏ธโƒฃ Heap์€ Young (Eden + S0 + S1) ๊ณผ Old ๋กœ ๋‚˜๋‰œ๋‹ค.

์•ฝํ•œ ์„ธ๋Œ€ ๊ฐ€์„ค์„ ํ™œ์šฉํ•ด ๊ฐ์ฒด์˜ ์ˆ˜๋ช…์— ๋”ฐ๋ผ ์˜์—ญ ๋ถ„๋ฆฌ. Young ๋น„์œจ ๋ณดํ†ต 1/3, Eden:S0:S1 = 8:1:1. Eden ์— ์ƒˆ ๊ฐ์ฒด โ†’ Minor GC ์‹œ ์‚ด์•„๋‚จ์œผ๋ฉด Survivor โ†’ ์ผ์ • ํšŸ์ˆ˜ ์‚ด์•„๋‚จ์œผ๋ฉด Old ๋กœ Promotion. ์ด ๊ตฌ์กฐ๊ฐ€ ์•ฝํ•œ ์„ธ๋Œ€ ๊ฐ€์„ค์˜ ์ •ํ™•ํ•œ ๊ตฌํ˜„.

2๏ธโƒฃ Survivor๊ฐ€ 2๊ฐœ์ธ ๊ฒƒ์€ Copying GC ๋ฅผ ์œ„ํ•จ์ด๋‹ค.

ํ•œ์ชฝ (From) ์€ ์‚ฌ์šฉ, ๋‹ค๋ฅธ ์ชฝ (To) ์€ ๋น„์–ด์žˆ์Œ. Minor GC ์‹œ [Eden + From] ์˜ ์‚ด์•„์žˆ๋Š” ๊ฐ์ฒด๋ฅผ [To] ๋กœ ๋ณต์‚ฌ ํ›„ ์›๋ณธ ๋น„์›€. ๋‹ค์Œ์—๋Š” ์—ญํ•  ๋ฐ”๋€œ. ์ž๋™ ์••์ถ• ํšจ๊ณผ + ๋‹จํŽธํ™” ํ•ด์†Œ. ๊ฐ์ฒด์˜ age ๊ฐ€ MaxTenuringThreshold (๊ธฐ๋ณธ 15) ๋„๋‹ฌ ์‹œ Old ๋กœ Promotion.

3๏ธโƒฃ Minor GC vs Major GC vs Full GC ๋ฅผ ์ •ํ™•ํžˆ ๊ตฌ๋ณ„ํ•ด์•ผ ํ•œ๋‹ค.

Minor GC = Young ๋งŒ (์ž์ฃผ, ๋น ๋ฆ„, ~ms), Major GC = Old ๋งŒ (๊ฐ€๋”, ๋А๋ฆผ, ~์ˆ˜๋ฐฑ ms), Full GC = ์ „์ฒด (๋งค์šฐ ๊ฐ€๋”, ๋งค์šฐ ๋А๋ฆผ, ~์ดˆ). Full GC ๊ฐ€ ์ž์ฃผ ๋ฐœ์ƒ = ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ์‹ ํ˜ธ โš ๏ธ. Card Table ๋กœ Old โ†’ Young ์ฐธ์กฐ๋ฅผ ์ถ”์ ํ•ด Minor GC ํšจ์œจ ์œ ์ง€. ๊ฑฐ๋Œ€ ๊ฐ์ฒด๋Š” ์ง์ ‘ Old ํ• ๋‹น ๋˜๋Š” Humongous (G1).


๐ŸŽ“ ํ•™์Šต ์ž๊ธฐ ์ ๊ฒ€

๊ธฐ๋ณธ ์ดํ•ด

  • Heap์˜ ์„ธ๋Œ€ ๊ตฌ์กฐ๋ฅผ ๊ทธ๋ฆด ์ˆ˜ ์žˆ๋‹ค (Eden, S0, S1, Old)
  • ๊ฐ์ฒด์˜ ์ผ์ƒ 5๋‹จ๊ณ„๋ฅผ ์„ค๋ช…ํ•  ์ˆ˜ ์žˆ๋‹ค
  • Minor/Major/Full GC ์˜ ์ฐจ์ด๋ฅผ ํ‘œ๋กœ ๊ทธ๋ฆด ์ˆ˜ ์žˆ๋‹ค
  • Tenuring Threshold ์˜ ์˜๋ฏธ๋ฅผ ์•ˆ๋‹ค

์‹ค์ „ ์ ์šฉ

  • ILIC ์ฝ”๋“œ์˜ ๊ฐ์ฒด๊ฐ€ ์–ด๋А ์˜์—ญ์— ๊ฐˆ์ง€ ์˜ˆ์ธกํ•  ์ˆ˜ ์žˆ๋‹ค
  • GC ๋กœ๊ทธ๋ฅผ ๋ณด๊ณ  Minor/Major/Full GC ๋ฅผ ๊ตฌ๋ณ„ํ•  ์ˆ˜ ์žˆ๋‹ค
  • Survivor ํฌ๊ธฐ ๋ชจ๋‹ˆํ„ฐ๋ง์„ ํ™œ์„ฑํ™”ํ•  ์ˆ˜ ์žˆ๋‹ค
  • static ์ปฌ๋ ‰์…˜์˜ Old ์˜์—ญ ๋ˆ„์  ์œ„ํ—˜์„ ์•ˆ๋‹ค

๋ฉด์ ‘ ๋Œ€๋น„ (3-5๋ถ„ ๋‹ต๋ณ€)

  • "๊ฐ์ฒด์˜ ์ผ์ƒ?" ๋‹ต๋ณ€ ๊ฐ€๋Šฅ
  • "Survivor ๊ฐ€ 2๊ฐœ์ธ ์ด์œ ?" ๋‹ต๋ณ€ ๊ฐ€๋Šฅ
  • "Minor vs Major vs Full GC?" ๋‹ต๋ณ€ ๊ฐ€๋Šฅ
  • "Promotion ์ด ๋ญ”๊ฐ€์š”?" ๋‹ต๋ณ€ ๊ฐ€๋Šฅ

์ž๊ธฐ ์ ๊ฒ€ ์งˆ๋ฌธ ๋‹ต๋ณ€

Q1: Survivor ๊ฐ€ ๋‘ ๊ฐœ (From, To) ๋กœ ๋‚˜๋‰˜์–ด ์žˆ๋Š” ์ด์œ ๋Š”?

ํ•œ ์ค„ ๋‹ต: Copying GC ๋ฅผ ํ™œ์šฉํ•˜๊ธฐ ์œ„ํ•ด. ํ•œ์ชฝ์€ ํ•ญ์ƒ ๋น„์–ด์žˆ์–ด ์‚ด์•„์žˆ๋Š” ๊ฐ์ฒด๋ฅผ ๊ทธ์ชฝ์œผ๋กœ ๋ณต์‚ฌํ•˜๋ฉด ์ž๋™ ์••์ถ• + ๋‹จํŽธํ™” ํ•ด์†Œ ํšจ๊ณผ.

์ƒ์„ธ ์„ค๋ช…:

1๊ฐœ Survivor ์˜ ๋ฌธ์ œ

๋งŒ์•ฝ Survivor ๊ฐ€ 1๊ฐœ๋ผ๋ฉด:

[Eden] [Survivor]
  ์ƒˆ ๊ฐ์ฒด   ์‚ด์•„๋‚จ์€ ๊ฐ์ฒด

Minor GC:
- Eden ์˜ ์‚ด์•„์žˆ๋Š” ๊ฐ์ฒด๋ฅผ Survivor ๋กœ ๋ณต์‚ฌ?
- ๊ทธ๋Ÿฐ๋ฐ Survivor ์•ˆ์—๋Š” ์ด๋ฏธ ๊ฐ์ฒด๋“ค ์žˆ์Œ
- โ†’ ์ถฉ๋Œ! ๋˜๋Š” ๋ณต์žกํ•œ ์••์ถ• ๋กœ์ง ํ•„์š”

๋ฌธ์ œ:

  • Survivor ์˜ ์‚ด์•„์žˆ๋Š” ๊ฐ์ฒด์™€ Eden ์˜ ์‚ด์•„์žˆ๋Š” ๊ฐ์ฒด๋ฅผ ์–ด๋–ป๊ฒŒ ํ•ฉ์น  ๊ฒƒ์ธ๊ฐ€
  • ๋‹จํŽธํ™” (๋นˆ ์ž๋ฆฌ) ์ฒ˜๋ฆฌ ์–ด๋ ค์›€
  • ๋ณต์žกํ•œ GC ์•Œ๊ณ ๋ฆฌ์ฆ˜ ํ•„์š”

2๊ฐœ Survivor ์˜ ์šฐ์•„ํ•œ ํ•ด๊ฒฐ

[Eden] [Survivor 0 (From)] [Survivor 1 (To)]
  ์ƒˆ ๊ฐ์ฒด   ํ˜„์žฌ ๊ฑฐ์ฃผ              ๋น„์–ด์žˆ์Œ

Minor GC ์‹œ:
1. [Eden + Survivor 0] ์˜ ์‚ด์•„์žˆ๋Š” ๊ฐ์ฒด ์‹๋ณ„
2. ๋ชจ๋‘ [Survivor 1] ๋กœ ๋ณต์‚ฌ
3. [Eden] ๋น„์›€
4. [Survivor 0] ๋น„์›€

After:
[Eden] [Survivor 0]      [Survivor 1]
  ๋น„์›€   ๋น„์›€             ํ˜„์žฌ ๊ฑฐ์ฃผ

๋‹ค์Œ Minor GC:
1. [Eden + Survivor 1] โ†’ [Survivor 0]
2. ์—ญํ•  ๋ฐ”๋€œ!

ํ•ต์‹ฌ ํšจ๊ณผ โญ :

1. Copying GC ์˜ ๋‹จ์ˆœํ•จ

  • ํ•œ ์˜์—ญ โ†’ ๋‹ค๋ฅธ ์˜์—ญ์œผ๋กœ ๋‹จ์ˆœ ๋ณต์‚ฌ
  • ์‚ด์•„์žˆ๋Š” ๊ฐ์ฒด๋งŒ โ†’ ์ž‘์—…๋Ÿ‰ ์ ์Œ
  • "์ „์ฒด๋ฅผ ๋น„์›€" โ†’ ๋‹จํŽธํ™” X

2. ์ž๋™ ์••์ถ• (Compact)

  • Copying ์ž์ฒด๊ฐ€ ์••์ถ• ํšจ๊ณผ
  • ๋ณ„๋„ Compact ๋‹จ๊ณ„ ๋ถˆํ•„์š”
  • ๋ฉ”๋ชจ๋ฆฌ ๋‹จํŽธํ™” ์ž์—ฐ์Šค๋Ÿฝ๊ฒŒ ํ•ด์†Œ

3. ๋น ๋ฅธ GC

  • ์‚ด์•„์žˆ๋Š” ๊ฐ์ฒด ์ ์Œ (๋Œ€๋ถ€๋ถ„ ๋‹จ๋ช…)
  • ๋ณต์‚ฌ ๋น„์šฉ ๋‚ฎ์Œ
  • โ†’ Minor GC ~10ms

๋น„์œ  โ€” ๋‘ ๊ฐœ์˜ ํ˜ธํ…” ๋ฐฉ

์†๋‹˜ (๊ฐ์ฒด) ์ด ํ˜ธํ…”์— ๋จธ๋ฌด๋Š” ์ƒํ™ฉ:

1๊ฐœ ๋ฐฉ๋งŒ ์žˆ๋‹ค๋ฉด:

  • ์ฒญ์†Œ ์‹œ ์†๋‹˜๊ณผ ์ง์„ ์–ด๋–ป๊ฒŒ?
  • ์ฒญ์†Œํ•˜๋ฉด์„œ ๋™์‹œ ์‚ฌ์šฉ ์–ด๋ ค์›€

2๊ฐœ ๋ฐฉ ์žˆ๋‹ค๋ฉด (์ž๋ฐ” ๋ฐฉ์‹):

  • ๋ฐฉ A ์— ์†๋‹˜๋“ค (ํ˜„์žฌ ๊ฑฐ์ฃผ)
  • ์ฒญ์†Œ ์‹œ: ์†๋‹˜๋“ค์„ ๋ฐฉ B ๋กœ ์˜ฎ๊น€
  • ๋ฐฉ A ํ†ต์งธ๋กœ ์ฒญ์†Œ (๋นˆ ๋ฐฉ ์ฒญ์†Œ๋Š” ์‰ฌ์›€)
  • ๋‹ค์Œ ์ฒญ์†Œ ๋•Œ: ๋ฐฉ B โ†’ ๋ฐฉ A

โ†’ ๊ฐ„๋‹จํ•˜๊ณ  ํšจ์œจ์ .


๊ฒฐ๋ก 

"Survivor ๊ฐ€ 2๊ฐœ์ธ ๊ฒƒ์€ Copying GC ์˜ ์ž์—ฐ์Šค๋Ÿฌ์šด ์š”๊ตฌ.
ํ•œ ์˜์—ญ์—์„œ ๋‹ค๋ฅธ ์˜์—ญ์œผ๋กœ์˜ ๋‹จ์ˆœ ๋ณต์‚ฌ๊ฐ€ ๊ฐ€์žฅ ํšจ์œจ์ ์ด๊ณ ,
์ž๋™ ์••์ถ• ํšจ๊ณผ + ๋‹จํŽธํ™” ํ•ด์†Œ ๋ผ๋Š” ๋ถ€์ˆ˜ ํšจ๊ณผ๊นŒ์ง€."


Q2: ๊ฑฐ๋Œ€ ๊ฐ์ฒด (Survivor ์˜์—ญ๋ณด๋‹ค ํฐ) ๋Š” ์–ด๋–ป๊ฒŒ ์ฒ˜๋ฆฌ๋˜๋Š”๊ฐ€?

ํ•œ ์ค„ ๋‹ต: ์ง์ ‘ Old ์˜์—ญ์— ํ• ๋‹น ๋˜๋Š” Humongous Region (G1 GC).

์ƒ์„ธ ์„ค๋ช…:

๊ฑฐ๋Œ€ ๊ฐ์ฒด์˜ ์ •์˜

byte[] hugeArray = new byte[100 * 1024 * 1024];  // 100MB

๊ฑฐ๋Œ€ ๊ฐ์ฒด = Survivor ์˜์—ญ๋ณด๋‹ค ํฐ ๊ฐ์ฒด.

์™œ ๋ฌธ์ œ์ธ๊ฐ€?:

1. Survivor ์— ์•ˆ ๋“ค์–ด๊ฐ

  • Survivor ๊ฐ€ 50MB ์ธ๋ฐ ๊ฐ์ฒด๊ฐ€ 100MB
  • โ†’ ๋ณต์‚ฌ ๋ถˆ๊ฐ€

2. ๋งค Minor GC ๋งˆ๋‹ค ํฐ ๋น„์šฉ

  • ๋งŒ์•ฝ Eden ์— ๋“ค์–ด๊ฐ”๋‹ค๋ฉด
  • Minor GC ์‹œ Survivor ๋กœ ๋ณต์‚ฌ ์‹œ๋„ โ†’ ์‹คํŒจ
  • ๋˜๋Š” ๋ณต์‚ฌํ•˜๋ฉด ๋งค์šฐ ๋А๋ฆผ

์ฒ˜๋ฆฌ ๋ฐฉ๋ฒ• 1: ์ง์ ‘ Old ํ• ๋‹น (Pretenuring)

JVM ์˜ต์…˜:

-XX:PretenureSizeThreshold=1m    # 1MB ์ด์ƒ์€ ์ง์ ‘ Old

๋™์ž‘:

byte[] huge = new byte[10 * 1024 * 1024];  // 10MB
// Eden ๊ฑฐ์น˜์ง€ ์•Š๊ณ  โ†’ Old ์ง์ ‘ ํ• ๋‹น

ํšจ๊ณผ:

  • Minor GC ์˜ํ–ฅ X
  • Survivor ๋ณต์‚ฌ ๋น„์šฉ X

๋‹จ์ :

  • Old ์˜์—ญ ๋น ๋ฅด๊ฒŒ ์ฐธ
  • Major GC ๋นˆ๋„ โ†‘

์ฒ˜๋ฆฌ ๋ฐฉ๋ฒ• 2: G1 ์˜ Humongous Object

G1 GC ๋Š” Region ๊ธฐ๋ฐ˜:

[Heap]
  โ”œโ”€โ”€ Region 0 (Eden, 1MB)
  โ”œโ”€โ”€ Region 1 (Eden, 1MB)
  โ”œโ”€โ”€ Region 2 (Survivor, 1MB)
  โ”œโ”€โ”€ Region 3 (Old, 1MB)
  โ”œโ”€โ”€ Region 4 (Humongous, 1MB)  โ† ํฐ ๊ฐ์ฒด
  โ””โ”€โ”€ ... ์ˆ˜๋ฐฑ ๊ฐœ

Humongous Object ์ •์˜:

  • Region ์˜ ์ ˆ๋ฐ˜ ์ด์ƒ ์ฐจ์ง€ํ•˜๋Š” ๊ฐ์ฒด
  • ๋ณ„๋„์˜ Humongous Region ์— ๋ฐฐ์น˜
  • ์—ฐ์†๋œ ์—ฌ๋Ÿฌ Region ์ฐจ์ง€ ๊ฐ€๋Šฅ

์˜ˆ์‹œ:

Region ํฌ๊ธฐ 1MB
๊ฐ์ฒด ํฌ๊ธฐ 3MB
โ†’ Humongous Region ์œผ๋กœ 3๊ฐœ ์—ฐ์† ์‚ฌ์šฉ

์ฒ˜๋ฆฌ ๋ฐฉ๋ฒ• 3: Region ํฌ๊ธฐ ์กฐ์ • (G1)

JVM ์˜ต์…˜:

-XX:G1HeapRegionSize=4m    # Region 4MB

ํšจ๊ณผ:

  • ๊ฐ™์€ ๊ฐ์ฒด๊ฐ€ Humongous ๊ฐ€ ์•ˆ ๋  ์ˆ˜๋„ ์žˆ์Œ
  • ์ผ๋ฐ˜ Old Region ์œผ๋กœ ์ฒ˜๋ฆฌ

ILIC ์ ์šฉ ์‹œ ๊ณ ๋ ค

์ƒํ™ฉ: ์šด์ž„ ๋ณด๊ณ ์„œ PDF ์ƒ์„ฑ

@Service
public class FareReportService {
    public byte[] generateMonthlyReport() {
        // 100MB PDF ์ƒ์„ฑ?
        byte[] pdfData = generatePdf(...);  // ๊ฑฐ๋Œ€ ๊ฐ์ฒด
        return pdfData;
    }
}

๋ฌธ์ œ:

  • pdfData ๊ฐ€ 100MB
  • Eden ์— ์•ˆ ๋“ค์–ด๊ฐ€๊ฑฐ๋‚˜, Survivor ๊ฑฐ์น˜๋ฉฐ ํฐ ๋น„์šฉ

ํ•ด๊ฒฐ:
1. Streaming:

public void streamReport(OutputStream out) {
    generatePdfStream(out);  // ๋ฉ”๋ชจ๋ฆฌ์— ๋‹ค ์•ˆ ์˜ฌ๋ฆผ
}
  1. Pretenuring:

    • JVM ์˜ต์…˜ ์กฐ์ • โ†’ ํฐ ๊ฐ์ฒด ์ง์ ‘ Old
  2. G1 + Humongous:

    • ์ž๋™์œผ๋กœ Humongous Region ์— ๋ฐฐ์น˜

๊ฒฐ๋ก 

"๊ฑฐ๋Œ€ ๊ฐ์ฒด๋Š” ์ผ๋ฐ˜ ๊ฐ์ฒด์™€ ๋‹ค๋ฅธ ๊ฒฝ๋กœ๋กœ ์ฒ˜๋ฆฌ.
Pretenuring (์ง์ ‘ Old) ๋˜๋Š” G1์˜ Humongous Region.
๊ฐ€๋Šฅํ•˜๋ฉด Streaming ๋“ฑ์œผ๋กœ ๊ฑฐ๋Œ€ ๊ฐ์ฒด ์ž์ฒด๋ฅผ ๋งŒ๋“ค์ง€ ์•Š๋Š” ๊ฒƒ์ด ์ตœ์„ ."


๋‹ค์Œ Unit์œผ๋กœ

  • GC ์•Œ๊ณ ๋ฆฌ์ฆ˜ 4๊ฐ€์ง€ ๋ฅผ ํ•™์Šตํ•  ์ค€๋น„ ์™„๋ฃŒ
  • Mark-Sweep, Mark-Compact, Copying, Generational ์˜ ์ฐจ์ด๊ฐ€ ๊ถ๊ธˆํ•˜๋‹ค
  • Reference Counting ์ด ์ž๋ฐ”์— ์•ˆ ์“ฐ์ด๋Š” ์ด์œ ๋ฅผ ๋งŒ๋‚  ์ค€๋น„ ์™„๋ฃŒ
















profile
Software Developer

0๊ฐœ์˜ ๋Œ“๊ธ€