๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜(GC) ํ•ด๋ถ€: ์ž๋ฐ” ๊ฐœ๋ฐœ์ž๊ฐ€ ๊ผญ ์•Œ์•„์•ผ ํ•  ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ์˜ ๋ชจ๋“  ๊ฒƒ

์ž๋ฐ” ๊ธฐ๋ฐ˜์˜ Spring Boot๋กœ ๋ฐฑ์—”๋“œ ๊ฐœ๋ฐœ์„ ํ•˜๋‹ค ๋ณด๋ฉด ์–ด๋А ์ˆœ๊ฐ„ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋А๋ ค์ง€๊ฑฐ๋‚˜ ์‹์€๋•€ ๋‚˜๊ฒŒ ๋งŒ๋“œ๋Š” OutOfMemoryError๊ฐ™์€ ์—๋Ÿฌ๋ฅผ ํ•œ๋ฒˆ์”ฉ์€ ๋ดค์„ ๊ฒƒ์ด๋‹ค. ์ด ๋•Œ GC์˜ ๋™์ž‘ ์›๋ฆฌ๋ฅผ ์ •ํ™•ํžˆ ์•Œ๊ณ  ์žˆ๋‹ค๋ฉด ๋ฌธ์ œ์˜ ์›์ธ์„ ์ฐพ์•„ ํ•ด๊ฒฐํ•˜๋Š”๋ฐ ๋งŽ์€ ๋„์›€์ด ๋œ๋‹ค. ์ด๋ฒˆ ํฌ์ŠคํŒ…์—์„œ๋Š” ์ž๋ฐ” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๊ฐœ๋ฐœํ•˜๋ฉด์„œ๋„ ๋ง‰์—ฐํžˆ ์•Œ๊ณ  ์žˆ๋˜ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜(GC)์— ๋Œ€ํ•ด์„œ ์ •๋ฆฌํ•ด ๋ณด๊ณ ์ž ํ•œ๋‹ค.

GC๋ฅผ ๋ฐฐ์›Œ์•ผ ํ•˜๋Š” ์ด์œ 

์ž๋ฐ”๋ฅผ ์ฒ˜์Œ ๋ฐฐ์šฐ๋ฉด ๊ฐ€์žฅ ๋จผ์ € ๋“ฃ๋Š” ์žฅ์  ์ค‘ ํ•˜๋‚˜๊ฐ€ ๋ฐ”๋กœ “์ž๋™ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ”๋‹ค. C ์–ธ์–ด๋‚˜ C++๊ฐ™์€ ์–ธ์–ด์—์„œ๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ malloc()์ด๋‚˜ calloc()์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๋™์ ์œผ๋กœ ํ• ๋‹นํ•˜๊ณ  free()๋กœ ์ง์ ‘ ๋™์  ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ•ด์ œํ•ด์•ผ ํ•œ๋‹ค. ์ด๋Š” ๊ฐœ๋ฐœ์ž๊ฐ€ ์‹ค์ˆ˜๋กœ ๋ฉ”๋ชจ๋ฆฌ ํ•ด์ œ ์ฝ”๋“œ๋ฅผ ๊นœ๋นกํ•˜๊ฒŒ ๋˜๋ฉด ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ์›์ธ์ด ๋  ์ˆ˜ ์žˆ๋‹ค. ํ˜น์€ ์ด๋ฏธ ํ•ด์ œ๋œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ฐธ์กฐํ•˜๋ฉด Segmentation Fault์™€ ํ•จ๊ป˜ ํ”„๋กœ์„ธ์Šค๊ฐ€ ์ข…๋ฃŒ๋˜๋Š” ๋ฌด์‹œ๋ฌด์‹œํ•œ ์ผ์„ ๊ฒช์„ ์ˆ˜๋„ ์žˆ๋‹ค. ์ž๋ฐ”๋Š” ์ด๋Ÿฌํ•œ ์œ„ํ—˜ํ•œ ์ž‘์—…์„ JVM์˜ GC์—๊ฒŒ ์ผ์ž„ํ•จ์œผ๋กœ์จ ์ž๋™์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ๋ฅผ ํ•˜๋„๋ก ํ•˜์—ฌ ๋น„์ฆˆ๋‹ˆ์Šค ๋กœ์ง์— ์กฐ๊ธˆ ๋” ์ง‘์ค‘ํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•œ๋‹ค.
ํ•˜์ง€๋งŒ GC๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ •๋ฆฌํ•˜๋Š” ๋™์•ˆ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์€ ์ž ์‹œ ๋ฉˆ์ถฐ์•ผ ํ•˜๋Š” Stop-The-World(STW)๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ๊ณ , GC๊ฐ€ ๋นˆ๋ฒˆํ•˜๊ฒŒ ๋ฐœ์ƒํ•˜๊ฑฐ๋‚˜ ๋„ˆ๋ฌด ์˜ค๋ž˜ ๋Œ๊ฒŒ๋˜๋ฉด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์„ฑ๋Šฅ์— ๋ง‰๋Œ€ํ•œ ์˜ํ–ฅ์„ ์ฃผ๊ฒŒ ๋œ๋‹ค.
๊ทธ๋ž˜์„œ ์šฐ๋ฆฌ๋Š” GC๊ฐ€ ์–ธ์ œ, ์–ด๋–ป๊ฒŒ, ์™œ ๋™์ž‘ํ•˜๋Š”์ง€ ์•Œ์•„์•ผ ์ด๋Ÿฌํ•œ ๋ฌธ์ œ์— ๋Œ€์ฒ˜ํ•  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ์ด๋‹ค.

์ƒํ˜ธ๋ฐฐํƒ€์  ์˜๋ฏธ

๊ฐœ๋ฐœ์ž๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ง์ ‘ ๊ด€๋ฆฌํ•˜๊ฒŒ ๋˜๋ฉด ํ• ๋‹น๊ณผ ํ•ด์ œ์— ์กฐ๊ธˆ ๋” ์‹ ๊ฒฝ์„ ์จ์•ผ ๊ฒ ์ง€๋งŒ ์ž๋ฐ”์˜ GC์™€ ๊ฐ™์€ ๋ฐฉ์‹์— ๋Œ€ํ•œ ํ•™์Šต์€ ๋œ ํ•„์š”ํ•˜๊ฒ ์ง€? ๋ฐ˜๋Œ€๋กœ ์ž๋ฐ”๋Š” GC๋ฅผ ํ†ตํ•ด ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น๊ณผ ํ•ด์ œ์— ์‹ ๊ฒฝ์“ธ ํ•„์š”๋Š” ์—†์ง€๋งŒ ๋‚ด๋ถ€ GC์˜ ๋™์ž‘ ์›๋ฆฌ์— ๋Œ€ํ•ด์„œ ์ดํ•ดํ•˜๊ณ  ์žˆ์–ด์•ผ ํ•˜๋Š” ํ•™์Šต ๊ณก์„ ์ด ์ƒ๊ธด๋‹ค. ์–ด์จŒ๋“  ์ž๋ฐ”๋กœ ๊ฐœ๋ฐœ์„ ํ•˜๊ธฐ๋กœ ํ•œ ์ด์ƒ GC๋Š” ํ•„์ˆ˜์ ์œผ๋กœ ์•Œ์•„์•ผ ํ•  ์š”์†Œ๋‹ค.

์ž๋ฐ” ๋ฉ”๋ชจ๋ฆฌ ๊ตฌ์กฐ

GC๋ฅผ ์ดํ•ดํ•˜๋ ค๋ฉด ๋จผ์ € GC๊ฐ€ ํ™œ๋™ํ•˜๋Š” ๋ฌด๋Œ€์ธ JVM์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ตฌ์กฐ๋ฅผ ์•Œ์•„์•ผ ํ•œ๋‹ค. JVM์ด ์šด์˜์ฒด์ œ๋กœ๋ถ€ํ„ฐ ํ• ๋‹น ๋ฐ›์€ ๋ฉ”๋ชจ๋ฆฌ๋Š” ํฌ๊ฒŒ 5๊ฐ€์ง€ ์˜์—ญ์œผ๋กœ ๋‚˜๋‰˜๋Š”๋ฐ ์•„๋ž˜ ๊ทธ๋ฆผ์€ Java8 ์ด์ƒ ๋ฒ„์ „์˜ JVM๋ฉ”๋ชจ๋ฆฌ ๊ตฌ์กฐ๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค.

ํž™ ์˜์—ญ (Heap Area)

  • ๋ชจ๋“  ์Šค๋ ˆ๋“œ๊ฐ€ ๊ณต์œ ํ•˜๋Š” ์˜์—ญ์ด๋‹ค.
  • new๋กœ ์ƒ์„ฑ๋œ ๋ชจ๋“  ๊ฐ์ฒด(Instance)์™€ ๋ฐฐ์—ด์ด ์ €์žฅ๋œ๋‹ค.
  • Java8 ๋ถ€ํ„ฐ๋Š” ์ •์ ๋ณ€์ˆ˜(static variable)์™€ ๋ฌธ์ž์—ด ํ’€(String Pool)๋„ ์ด๊ณณ์— ์ƒ์ฃผํ•˜๊ณ  GC์˜ ์ฃผ์š” ํƒ€๊ฒŸ์ด ๋œ๋‹ค.

๋ฉ”์„œ๋“œ ์˜์—ญ (Method Area / Metaspace)

  • ๋ชจ๋“  ์Šค๋ ˆ๋“œ๊ฐ€ ๊ณต์œ ํ•˜๋Š” ์˜์—ญ์ด๋‹ค.
  • ํด๋ž˜์Šค ์ด๋ฆ„, ๋ถ€๋ชจ ํด๋ž˜์Šค ์ด๋ฆ„, ๋ฉ”์„œ๋“œ ์ •๋ณด, ๋ฐ”์ดํŠธ์ฝ”๋“œ๋“ฑ ํด๋ž˜์Šค ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ๊ฐ€ ์ €์žฅ๋œ๋‹ค.
  • Java8 ๋ถ€ํ„ฐ๋Š” Metaspace๋ผ๋Š” ์ด๋ฆ„์œผ๋กœ ๋ถˆ๋ฆฌ๋ฉฐ JVM ํž™์ด ์•„๋‹Œ OS์˜ ๋„ค์ดํ‹ฐ๋ธŒ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

์Šคํƒ (Stack Area)

  • ๊ฐ ์Šค๋ ˆ๋“œ๋งˆ๋‹ค ๋ณ„๋„๋กœ ์ƒ์„ฑ๋œ๋‹ค. (๊ณต์œ  ์•ˆ ๋จ)
  • ๋ฉ”์„œ๋“œ ์‹คํ–‰์‹œ ํ•„์š”ํ•œ ์ง€์—ญ๋ณ€์ˆ˜, ๋งค๊ฐœ๋ณ€์ˆ˜, ๋ฆฌํ„ด ๊ฐ’๋“ฑ์ด ์ž„์‹œ๋กœ ์ €์žฅ๋œ๋‹ค.
  • ๋ฉ”์„œ๋“œ ์ˆ˜ํ–‰์ด ๋๋‚˜๋ฉด ์ฆ‰์‹œ ์‚ญ์ œ๋˜์–ด ๊นจ๋—ํ•˜๊ฒŒ ๊ด€๋ฆฌ๋œ๋‹ค. GC์˜ ๋Œ€์ƒ์ด ์•„๋‹ˆ๋‹ค.

PC ๋ ˆ์ง€์Šคํ„ฐ

  • ๊ฐ ์Šค๋ ˆ๋“œ๋งˆ๋‹ค ์กด์žฌํ•œ๋‹ค.
  • ํ˜„์žฌ ์Šค๋ ˆ๋“œ๊ฐ€ ์‹คํ–‰ ์ค‘์ธ JVM๋ช…๋ น(Instruction)์˜ ์ฃผ์†Œ๋ฅผ ๊ธฐ๋กํ•œ๋‹ค.
  • CPU์˜ ๋ ˆ์ง€์Šคํ„ฐ์™€ ์œ ์‚ฌํ•˜๊ฒŒ ๋‹ค์Œ์— ์‹คํ–‰ํ•  ์ฝ”๋“œ ๋ผ์ธ์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ํฌ์ธํ„ฐ ์—ญํ• ์„ ํ•œ๋‹ค.

๋„ค์ดํ‹ฐ๋ธŒ ๋ฉ”์„œ๋“œ ์Šคํƒ

  • ๊ฐ ์Šค๋ ˆ๋“œ๋งˆ๋‹ค ์กด์žฌํ•œ๋‹ค.
  • ์ž๋ฐ”๊ฐ€ ์•„๋‹Œ ๋‹ค๋ฅธ ์–ธ์–ด(C, C++๋“ฑ)์œผ๋กœ ๊ฐœ๋ฐœ๋œ ๋„ค์ดํ‹ฐ๋ธŒ ์ฝ”๋“œ๋ฅผ ์‹คํ–‰ํ•  ๋•Œ ์‚ฌ์šฉํ•˜๋Š” ์Šคํƒ์ด๋‹ค.
  • JNI๋ฅผ ํ†ตํ•ด ํ˜ธ์ถœ๋˜๋Š” ๋ฉ”์„œ๋“œ๋ฅผ ์œ„ํ•œ ๊ณต๊ฐ„์ด๋‹ค. ๋„ค์ดํ‹ฐ๋ธŒ ์˜์—ญ์ด๋ผ GC์˜ ๋Œ€์ƒ์ด ์•„๋‹ˆ๋‹ค.

์ด 5๊ฐ€์ง€ ์˜์—ญ ์ค‘์—์„œ ํŠนํžˆ ํž™(Heap)๊ณผ ์Šคํƒ(Stack) ์˜์—ญ์˜ ์ƒํ˜ธ์ž‘์šฉ์ด ์ž๋ฐ” ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ํ•ต์‹ฌ์ด๋ผ๊ณ  ํ•  ์ˆ˜ ์žˆ๋‹ค.

๋ฉ”์„œ๋“œ ์˜์—ญ PermGen์—์„œ Metaspace๋กœ ์ง„ํ™”

์ž๋ฐ”8 ์ด์ „๊ณผ ์ดํ›„ ๋ฉ”๋ชจ๋ฆฌ ๊ตฌ์กฐ์— ๋ณ€ํ™”๊ฐ€ ์žˆ์—ˆ๋Š”๋ฐ ์ฃผ์š” ๋ณ€ํ™”๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  • Java8 ์ด์ „ (PermGen)
    • ํด๋ž˜์Šค ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ(ํด๋ž˜์Šค ์ด๋ฆ„, ๋ฉ”์„œ๋“œ ์ •๋ณด๋“ฑ)์™€ ์ •์  ๋ณ€์ˆ˜, ์ƒ์ˆ˜ ํ’€ ๋“ฑ์ด PermGen์ด๋ผ๋Š” ์˜์—ญ์— ์ €์žฅ๋˜์—ˆ๋‹ค.
    • PermGen์€ ํž™์˜ ์ผ๋ถ€์ฒ˜๋Ÿผ ๊ด€๋ฆฌ๋˜๊ณ  ํฌ๊ธฐ๊ฐ€ ๊ณ ์ •์ด๋ผ์„œ ์ •์  ๋ณ€์ˆ˜๋ฅผ ๋„ˆ๋ฌด ๋งŽ์ด ์“ฐ๊ฑฐ๋‚˜ ํด๋ž˜์Šค๋ฅผ ๋งŽ์ด ๋กœ๋”ฉํ•˜๋ฉด OutOfMemoryError ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•˜์—ฌ ๊ฝค๋‚˜ ๊ณจ์นซ๊ฑฐ๋ฆฌ์˜€๋‹ค.
  • Java8 ์ดํ›„ (Metaspace)
    • ๊ธฐ์กด์˜ PermGen์— ์ €์žฅ๋˜๋˜ ํด๋ž˜์Šค ๋ฉ”ํƒ€๋ฐ์ดํ„ฐ ์ •๋ณด๊ฐ€ ์ด๊ณณ์— ์ €์žฅ๋œ๋‹ค.
    • PermGen์ด ์‚ฌ๋ผ์ง€๊ณ  Metaspace๊ฐ€ ๋“ฑ์žฅํ–ˆ๋‹ค.
    • Metaspace๋Š” JVM์˜ ํž™ ์˜์—ญ์ด ์•„๋‹Œ OS์˜ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๋Š”๋ฐ RAM์ด ํ—ˆ์šฉํ•˜๋Š” ํ•œ ํฌ๊ธฐ๊ฐ€ ๋™์ ์œผ๋กœ ๋Š˜์–ด๋‚  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ๋กœ๋”ฉ๋˜๋Š” ํด๋ž˜์Šค๊ฐ€ ๋งŽ๋”๋ผ๋„ OutofMemoryError ๋ฐœ์ƒ ์œ„ํ—˜์„ ํฌ๊ฒŒ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.

ํด๋ž˜์Šค ๋ฉ”ํƒ€ ์ •๋ณด ์ด์™ธ์— ์ •์  ๋ณ€์ˆ˜์™€ ์ƒ์ˆ˜ ํ’€ ๋ฐ์ดํ„ฐ๋Š” Heap ์˜์—ญ์œผ๋กœ ์ด๋™๋˜์–ด ๊ณผ๊ฑฐ์˜ PermGen์—์„œ GC๊ฐ€ ์ž˜ ์•ˆ๋˜๋˜ ๋ถ€๋ถ„์„ ๋” ๋ช…ํ™•ํ•œ GC ๊ด€๋ฆฌ ๋Œ€์ƒ์œผ๋กœ ์ด์ „์„ ํ–ˆ๋‹ค.

๊ฐ€๋น„์ง€ ์ปฌ๋ ‰ํ„ฐ(GC)์˜ ๋™์ž‘ ์›๋ฆฌ

์ด์ œ GC๊ฐ€ ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š”์ง€ ์‚ดํŽด๋ณด์ž. GC๊ฐ€ ํ•˜๋Š” ์ผ์€ ๋‹จ์ˆœํ•˜๊ฒŒ ์ƒ๊ฐํ•˜๋ฉด ์“ฐ๋ ˆ๊ธฐ ์ฐพ๊ธฐ์™€ ๋ฒ„๋ฆฌ๊ธฐ๋‹ค.

Reachability: ๋ฌด์—‡์ด ์“ฐ๋ ˆ๊ธฐ์ง€?

GC๋Š” ์–ด๋–ค ๊ฐ์ฒด๋ฅผ ์‚ญ์ œํ•ด์•ผ ํ• ์ง€ ์–ด๋–ป๊ฒŒ ํŒ๋‹จํ• ๊นŒ? ์ž๋ฐ”๋Š” ๋„๋‹ฌ ๊ฐ€๋Šฅ์„ฑ(Reachability)๋ผ๋Š” ๊ฐœ๋…์„ ์‚ฌ์šฉํ•œ๋‹ค.

  • Reachable: ๋ˆ„๊ตฐ๊ฐ€ ์ž์‹ ์„ ์ฐธ์กฐํ•˜๊ณ  ์žˆ์–ด์„œ ์œ ํšจํ•œ ์ƒํƒœ
  • Unreachable: ์•„๋ฌด๋„ ์ž์‹ ์„ ์ฐธ์กฐํ•˜๊ณ  ์žˆ์ง€ ์•Š์•„์„œ ์“ฐ๋ ˆ๊ธฐ๋กœ ์ „๋ฝํ•  ์ƒํƒœ – ์ˆ˜๊ฑฐ ๋Œ€์ƒ (Garbage)

๊ทธ๋ ‡๋‹ค๋ฉด “์ฐธ์กฐํ•˜๊ณ  ์žˆ๋‹ค”๋Š” ๊ฑด ์–ด๋””์„œ๋ถ€ํ„ฐ ์ฐธ์กฐ๋ฅผ ๋งํ•˜๋Š” ๊ฑธ๊นŒ? ๊ทธ ์‹œ์ž‘์ ์ด ๋˜๋Š” ๊ฐ์ฒด๋“ค์„ GC Root์ด๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค. GC Root์—์„œ ์‹œ์ž‘ํ•ด์„œ ์ฐธ์กฐ ์—ฐ๊ฒฐ์ด ์ด์–ด์ง€๋Š” ๊ฐ์ฒด๋Š” ์‚ด๋ ค๋‘๊ณ  ์ด์–ด์ง€์ง€ ์•Š๋Š” ๊ฐ์ฒด๋Š” ๋ฒ„๋ฆฐ๋‹ค.

๋Œ€ํ‘œ์ ์ธ GC Root

  1. ์Šคํƒ(Stack)์˜ ์ง€์—ญ ๋ณ€์ˆ˜ ๋ฐ ๋งค๊ฐœ๋ณ€์ˆ˜: ํ˜„์žฌ ์‹คํ–‰ ์ค‘์ธ ๋ฉ”์„œ๋“œ ์•ˆ์—์„œ ์‚ฌ์šฉ ์ค‘์ธ ๋ณ€์ˆ˜๋“ค์ด ๊ฐ€๋ฆฌํ‚ค๋Š” ๊ฐ์ฒด๋Š” ๋‹น์—ฐํžˆ ์‚ด๋ ค์•ผ ํ•œ๋‹ค.
  2. ํ™œ์„ฑ ์Šค๋ ˆ๋“œ(Active Thread): ์‹คํ–‰ ์ค‘์ธ ์Šค๋ ˆ๋“œ ์ž์ฒด๋„ ๋ฃจํŠธ๊ฐ€ ๋œ๋‹ค.
  3. ์ •์  ๋ณ€์ˆ˜(Static Variable): ํด๋ž˜์Šค์˜ static ํ•„๋“œ์—์„œ ์ฐธ์กฐํ•˜๋Š” ๊ฐ์ฒด๋“ค์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋๋‚  ๋•Œ๊นŒ์ง€ ์‚ด์•„์žˆ์–ด์•ผ ํ•˜๋Š” ๊ฒฝ์šฐ๊ฐ€ ๋งŽ๋‹ค.
  4. JNI ์ฐธ์กฐ: C/C++ ๊ฐ™์€ ๋„ค์ดํ‹ฐ๋ธŒ ์ฝ”๋“œ์—์„œ ๋งŒ๋“  ๊ฐ์ฒด ์ฐธ์กฐ๋‹ค.

GC Root๊ฐ€ ๋  ์ˆ˜ ์žˆ๋Š” ๊ฒƒ๋“ค์€ ๋Œ€๋ถ€๋ถ„ ํž™ ์˜์—ญ ๋ฐ–์— ์žˆ๋Š” ์กด์žฌ๋“ค์ด๋‹ค. ํž™ ๋ฐ–์—์„œ ํž™ ์•ˆ์„ ๊ฐ€๋ฆฌํ‚ค๋Š” ํ™”์‚ดํ‘œ๊ฐ€ ๋ฐ”๋กœ ์ƒ๋ช…์ค„์ด๋‹ค.

Mark-and-Sweep

GC๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ Mark-and-Sweep ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ•˜๋Š”๋ฐ ๊ฐœ๋…์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

  1. Mark(ํ‘œ์‹œํ•˜๊ธฐ): GC๋Š” ๋ชจ๋“  GC Root์—์„œ ์‹œ์ž‘ํ•ด์„œ ์ฐธ์กฐ๋œ ๊ฐ์ฒด๋“ค์„ ์ญ‰ ์‚ดํŽด๋ณธ๋‹ค. ์ฐธ์กฐ๊ฐ€ ์œ ์ง€๋˜๋Š” ๊ฐ์ฒด๋Š” ๋งˆํฌ๋ฅผ ํ•ด๋‘”๋‹ค.
  2. Sweep(์“ธ์–ด๋‹ด๊ธฐ): ํž™ ๋ฉ”๋ชจ๋ฆฌ ์ „์ฒด๋ฅผ ํ›‘์œผ๋ฉด์„œ ๋งˆํฌ๊ฐ€ ์—†๋Š” ๊ฐ์ฒด๋“ค์€ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ํ•ด์ œํ•œ๋‹ค.
  3. Compact(์••์ถ•ํ•˜๊ธฐ): ์ค‘๊ฐ„์ค‘๊ฐ„์— ํ•ด์ œ๋œ ๋ฉ”๋ชจ๋ฆฌ ๋•Œ๋ฌธ์— ๋นˆ๊ณต๊ฐ„์ด ์ƒ๊ธฐ๋Š” ์ด๋ฅธ๋ฐ” ๋ฉ”๋ชจ๋ฆฌ ํŒŒํŽธํ™”๊ฐ€ ๋ฐœ์ƒํ•˜๋Š”๋ฐ ํŒŒํŽธํ™”๊ฐ€ ์‹ฌํ•  ์ˆ˜๋ก ์‚ฌ์ด์ฆˆ๊ฐ€ ํฐ ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๋•Œ ์ž๋ฆฌ๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— ๋ฌธ์ œ๊ฐ€ ์ƒ๊ธธ ์ˆ˜ ์žˆ๋‹ค. ๊ทธ๋ž˜์„œ ์ƒ์กดํ•œ ๊ฐ์ฒด๋“ค์„ ํ•œ์ชฝ์œผ๋กœ ๋ชจ์•„์„œ ๋นˆ ๊ณต๊ฐ„์„ ํฌ๊ฒŒ ํ™•๋ณดํ•˜๋Š” ์ž‘์—…์„ ๋งํ•œ๋‹ค.

Stop-The-World (STW)

GC๊ฐ€ ์—ด์‹ฌํžˆ ์ฒญ์†Œ๋ฅผ ํ•˜๋Š” ๋™์•ˆ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ๋ชจ๋“  ์Šค๋ ˆ๋“œ๋Š” ์ผ์‹œ ์ •์ง€ํ•œ๋‹ค. ์—„๋งˆ๊ฐ€ ๋ฐฉ์„ ์ฒญ์†Œํ•˜๊ณ  ์žˆ๋Š”๋ฐ ์•„์ด๊ฐ€ ๊ณ„์† ์–ด์ง€๋Ÿฝํžˆ๋ฉด ์ •๋ฆฌ๊ฐ€ ์•ˆ๋œ๋‹ค๊ณ  ์ƒ๊ฐํ•˜๋ฉด ์‰ฝ๋‹ค. GC๊ฐ€ ๊ฐ์ฒด์˜ ์ƒ์กด ์—ฌ๋ถ€๋ฅผ ํŒ๋‹จํ•˜๊ณ  ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์˜ฎ๊ธฐ๋Š” ์ค‘์—(Compaction) ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋ฅผ ๋งŒ๋“ค๊ฑฐ๋‚˜ ์ฐธ์กฐ๋ฅผ ๋ฐ”๊พธ๋ฉด ๊ผฌ์ผ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.
์šฐ๋ฆฌ๊ฐ€ ํ”ํžˆ ๋งํ•˜๋Š” GC ํŠœ๋‹์ด ๋ฐ”๋กœ ์ด STW ์‹œ๊ฐ„์„ ์ค„์—ฌ ๋ชจ๋“  ์Šค๋ ˆ๋“œ๊ฐ€ ๋ฉˆ์ถ”๋Š” ์‹œ๊ฐ„์„ ์ตœ์†Œํ™”ํ•˜๊ธฐ ์œ„ํ•œ ๋…ธ๋ ฅ์ธ ๊ฒƒ์ด๋‹ค.

๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜(GC) ๋งค์นด๋‹ˆ์ฆ˜

์ด์ œ ์กฐ๊ธˆ ๋” ๊นŠ๊ฒŒ GC์˜ ๋™์ž‘์— ๋Œ€ํ•ด์„œ ์‚ดํŽด๋ณด์ž. ์ž๋ฐ”๋Š” ํšจ์œจ์ ์ธ GC๋ฅผ ์œ„ํ•ด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ์ „์ œ๋ฅผ ๋‘๊ณ  ์ž‘๋™ํ•œ๋‹ค.

  • ๋Œ€๋ถ€๋ถ„์˜ ๊ฐ์ฒด์˜ ์ƒ๋ช… ์ฃผ๊ธฐ๋Š” ์งง์„ ๊ฒƒ์ด๋‹ค. (๋Œ€๋ถ€๋ถ„์˜ ๊ฐ์ฒด๊ฐ€ ์ฐธ์กฐ๋œ ์ดํ›„ ๊ธˆ๋ฐฉ Unreachable ์ƒํƒœ๊ฐ€ ๋  ๊ฒƒ์ด๋‹ค.)
  • ์˜ค๋ž˜๋œ ๊ฐ์ฒด์—์„œ ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋กœ์˜ ์ฐธ์กฐ๋Š” ๋งค์šฐ ์ ๊ฒŒ ๋ฐœ์ƒํ•  ๊ฒƒ์ด๋‹ค.

์‰ฝ๊ฒŒ ๋งํ•ด ์šฐ๋ฆฌ๊ฐ€ for๋ฌธ ์•ˆ์—์„œ ๋งŒ๋“œ๋Š” ์ž„์‹œ ๋ณ€์ˆ˜๋‚˜ DTO ๊ฐ™์€ ๊ฒƒ๋“ค์€ ์ž ๊น ์“ฐ์ด๊ณ  ๋ฐ”๋กœ ๋ฒ„๋ ค์งˆ ๊ฒƒ์ด๋‹ค. ๊ทธ๋ž˜์„œ JVM์€ ํž™์„ Young Generation๊ณผ Old Generation์œผ๋กœ ๋‚˜๋ˆ„์–ด ๊ด€๋ฆฌํ•œ๋‹ค.

Young Generation ์˜์—ญ

Young Generation ์˜์—ญ์€ 3๊ฐœ์˜ ๊ตฌ์—ญ์œผ๋กœ ๋‚˜๋ˆˆ๋‹ค.

  • Eden: ๊ฐ์ฒด๊ฐ€ ์ฒ˜์Œ ์ƒ์„ฑ๋˜๋ฉด ์ƒ์ฃผํ•˜๋Š” ๊ณณ์ด๋‹ค. (ํƒœ์–ด๋‚˜๋Š” ๊ณณ)
  • Survivor0 (S0) & Survivor1 (S1): Eden์—์„œ ์‚ด์•„๋‚จ์€ ๊ฐ์ฒด๋“ค์ด ์˜ฎ๊ฒจ์ง€๋Š” ๊ณณ์ด๋‹ค.

Eden ์˜์—ญ์ด ๋ชจ๋‘ ์ฐจ๋ฉด Minor GC๊ฐ€ ์ผ์–ด๋‚˜๋Š”๋ฐ Minor GC์˜ ๋ชฉ์ ์€ Young Generation ์˜์—ญ(Eden + S0 + S1) ์ „์ฒด๋ฅผ ์ฒญ์†Œํ•˜๋Š” ๊ฒƒ์ด๋‹ค. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๊ตฌ๋™ ํ›„ GC๊ฐ€ ์ฒ˜์Œ ์ผ์–ด๋‚  ๋•Œ Young Generation์˜ ๋™์ž‘๊ณผ์ •์€ ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.
์ฒ˜์Œ GC๊ฐ€ ๋ฐœ์ƒํ•  ๋•Œ๋Š” S0, S1 ์˜์—ญ์—๋Š” ๊ฐ์ฒด๊ฐ€ ์—†๊ธฐ ๋•Œ๋ฌธ์— S0, S1 ์˜์—ญ์€ ๋ณด์ง€ ์•Š์„ ๊ฒƒ์ด๋‹ค.

  1. ์ƒˆ๋กœ ํƒœ์–ด๋‚œ ๊ฐ์ฒด๋Š” ๋ฌด์กฐ๊ฑด Eden ์˜์—ญ์— ์ƒ์ฃผํ•œ๋‹ค.
  2. Eden์ด ๋ชจ๋‘ ์ฐจ๋ฉด Minor GC๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
  3. Eden์— ์žˆ๋Š” ๊ฐ์ฒด ์ค‘ reachableํ•œ ๊ฐ์ฒด๋งŒ ๊ณจ๋ผ์„œ ๋น„์–ด์žˆ๋Š” S0 ์˜์—ญ์œผ๋กœ ๋ณต์‚ฌํ•œ๋‹ค.
  4. S0์œผ๋กœ ์ด๋™ํ•œ ๊ฐ์ฒด์˜ Age๋ฅผ ์ฆ๊ฐ€์‹œํ‚จ๋‹ค.
  5. Eden์˜ ๋‚˜๋จธ์ง€ ์“ฐ๋ ˆ๊ธฐ(unreachable) ๊ฐ์ฒด๋“ค์€ ์‹น ์ •๋ฆฌํ•œ๋‹ค.

๋‹ค์Œ GC๋ถ€ํ„ฐ๋Š” Young Generation์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ๋™์ž‘ํ•œ๋‹ค.

  1. Eden ์˜์—ญ๊ณผ S0 ์˜์—ญ์˜ ๋ชจ๋“  reachableํ•œ ๊ฐ์ฒด๋ฅผ S1์œผ๋กœ ์ด๋™์‹œํ‚จ๋‹ค.
  2. S1์œผ๋กœ ์ด๋™ํ•œ ๊ฐ์ฒด์˜ Age๋ฅผ ์ฆ๊ฐ€์‹œํ‚จ๋‹ค.
  3. Eden ์˜์—ญ๊ณผ S0 ์˜์—ญ์˜ ๋ชจ๋“  ์“ฐ๋ ˆ๊ธฐ(unreachable) ๊ฐ์ฒด๋“ค์„ ์ •๋ฆฌํ•œ๋‹ค.
  4. ๋‹ค์Œ Minor GC์—์„œ Eden๊ณผ S1์˜ ๋ชจ๋“  reachableํ•œ ๊ฐ์ฒด๋ฅผ S0๋กœ ์ด๋™์‹œํ‚จ๋‹ค.
  5. S0์œผ๋กœ ์ด๋™ํ•œ ๊ฐ์ฒด์˜ Age๋ฅผ ์ฆ๊ฐ€์‹œํ‚จ๋‹ค.

์œ„์™€ ๊ฐ™์€ ๊ณผ์ •์„ ๋ฐ˜๋ณตํ•˜๋ฉด์„œ ์‚ด์•„๋‚จ์€ ๊ฐ์ฒด๋“ค์€ S0์™€ S1์„ ๋ฐ˜๋ณต์ ์œผ๋กœ ์ด๋™ํ•˜๊ฒŒ ๋˜๊ณ  ๊ทธ ๋•Œ๋งˆ๋‹ค Age๊ฐ€ ์ฆ๊ฐ€ ๋œ๋‹ค.
์–ด๋А ์ •๋„ ๋‚˜์ด(Age)๋ฅผ ๋จน์€ ๊ฐ์ฒด๋“ค์€ ํŠน์ • ๊ฐ’์„ ๋„˜์–ด์„œ๋Š” ์ˆœ๊ฐ„ Old ์„ธ๋Œ€๊ฐ€ ๋œ๋‹ค.

S0์™€ S1์„ ๋ฐ˜๋ณต์ ์œผ๋กœ ์ด๋™ํ•˜๋ฉด์„œ ํ•œ์ชฝ Survivor ์˜์—ญ์„ ๋น„์šฐ๋Š” ์ด์œ ๊ฐ€ ๋ฐ”๋กœ ํŒŒํŽธํ™”๋ฅผ ๋ฐฉ์ง€ํ•˜๊ธฐ ์œ„ํ•œ ๊ฒƒ์ด๋‹ค.

Old Generation ์˜์—ญ

Young ์˜์—ญ์—์„œ ์˜ค๋žซ๋™์•ˆ ์‚ด์•„๋‚จ์€ ๊ฐ์ฒด๋“ค์€ ๋‚˜์ด(Age)๊ฐ€ ๊ธฐ์ค€์„ ๋„˜๊ธฐ๋ฉด Old Generation ์˜์—ญ์œผ๋กœ ์ด๋™ํ•˜๊ฒŒ ๋œ๋‹ค. ์ด๊ฒƒ์„ Promotion(์Šน๊ธ‰)์ด๋ผ๊ณ  ํ•˜๋ฉฐ Old ์˜์—ญ์€ Young ์˜์—ญ๋ณด๋‹ค ํฌ๊ธฐ๊ฐ€ ํฌ๋‹ค. ๋งŒ์•ฝ Old Generation์ด ๊ฐ€๋“ ์ฐจ๊ฒŒ๋˜๋ฉด Major GC ํ˜น์€ Full GC๊ฐ€ ๋ฐœ์ƒํ•˜๋Š”๋ฐ Major GC๋Š” ํž™ ์ „์ฒด๋ฅผ ์ฒญ์†Œํ•˜๊ณ  Minor GC๋ณด๋‹ค STW ์‹œ๊ฐ„์ด ๋” ๊ธธ๋‹ค. ์•ž์„  ์ „์ œ๋ฅผ ํ†ตํ•ด ๋ดค์„ ๋•Œ Major GC๊ฐ€ ์ž์ฃผ ๋ฐœ์ƒํ•œ๋‹ค๋Š” ๊ฒƒ์€ ์‹ฌ๊ฐํ•œ ์„ฑ๋Šฅ ์ €ํ•˜๊ฐ€ ๋ฐœ์ƒํ•  ์ˆ˜ ์žˆ์œผ๋ฉฐ ์–ด๋””์„ ๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ๋ฐœ์ƒํ•˜๊ณ  ์žˆ์Œ์„ ์˜์‹ฌํ•ด ๋ด์•ผ ํ•œ๋‹ค.

Promotion: ์Šน๊ธ‰ ์กฐ๊ฑด๊ณผ MaxTenuringThreshold

๊ฐ์ฒด๊ฐ€ Old ์˜์—ญ์œผ๋กœ ๊ฐ€๊ธฐ ์œ„ํ•œ ๋‚˜์ด ๊ธฐ์ค€ ๊ฐ’์€ MaxTenuringThreshold ๋ผ๋Š” ์˜ต์…˜์œผ๋กœ ๊ฒฐ์ •๋œ๋‹ค.

  • ๊ธฐ๋ณธ๊ฐ’: ๋ณดํ†ต 15์ด๊ณ  Minor GC๋ฅผ 15๋ฒˆ ๋ฒ„ํ…จ์•ผ Old ์˜์—ญ์œผ๋กœ ๊ฐˆ ์ž๊ฒฉ์ด ์ฃผ์–ด์ง„๋‹ค.
  • ๋™์  ์กฐ์ •: JVM์€ ์ƒํ™ฉ์— ๋”ฐ๋ผ ์ด ๊ฐ’์„ ์œ ๋™์ ์œผ๋กœ ์ค„์ด๊ธฐ๋„ ํ•œ๋‹ค. ๋งŒ์•ฝ Survivor ์˜์—ญ์˜ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ๋ถ€์กฑํ•˜๋ฉด ๋‚˜์ด๊ฐ€ 15๊ฐ€ ์•ˆ๋˜๋”๋ผ๋„ Old ์˜์—ญ์œผ๋กœ ๋ณด๋‚ผ ์ˆ˜ ์žˆ๋‹ค.
New ๋ผ๊ณ  ํ‘œ์‹œ๋œ ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋“ค์ด Young Generation๋‚ด์˜ Eden ์˜์—ญ์œผ๋กœ ๋“ค์–ด์™€ ์Œ“์ธ๋‹ค. Survivor0(S0), Survivor(S1), Old Generation์˜์—ญ์€ ์•„์ง ๋น„์–ด์žˆ๋Š” ์ƒํƒœ๋‹ค.
Eden ์˜์—ญ์ด ๊ฐ์ฒด๋กœ ๊ฐ€๋“์ฐจ๋ฉด Minor GC๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ์ด๋•Œ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ๊ฐ์ฒด๋Š” ์ œ๊ฑฐ๋˜๊ณ  ์‚ด์•„์žˆ๋Š” ๊ฐ์ฒด๋Š” Survivor ์˜์—ญ (์—ฌ๊ธฐ์„œ๋Š” S0)์œผ๋กœ ์ด๋™ํ•˜๋ฉด ๋‚˜์ด(Age)๊ฐ€ 1 ์ฆ๊ฐ€ํ•œ๋‹ค.
Survivor ์˜์—ญ์—์„œ ์—ฌ๋Ÿฌ ๋ฒˆ์˜ Minor GC๋ฅผ ๊ฑฐ์น˜๋ฉฐ ์‚ด์•„๋‚จ์•„ ํŠน์ • ๋‚˜์ด์— ๋„๋‹ฌํ•œ ๊ฐ์ฒด๋“ค์€ Old Generation์œผ๋กœ ์ด๋™ํ•œ๋‹ค. (Promotion) 
Old Generation์ด ๊ฐ€๋“ ์ฐฌ ์ƒํƒœ์—์„œ Major GC๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค. ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š” ๊ฐ์ฒด๋“ค์€ ์ œ๊ฑฐ๋˜๊ณ (ํ๋ฆฐ ํ‘œํ˜„) ์‚ด์•„๋‚จ์€ ๊ฐ์ฒด๋“ค์€ ํ•œ์ชฝ์œผ๋กœ ๋ชจ์—ฌ ์••์ถ•ํ•œ๋‹ค. ์ด ๊ณผ์ •์€ Old Generation์˜ ๊ณต๊ฐ„์„ ํšจ์œจ์ ์œผ๋กœ ํ™•๋ณดํ•œ๋‹ค.

๋‹ค์–‘ํ•œ GC ์•Œ๊ณ ๋ฆฌ์ฆ˜

์ž๋ฐ”๋Š” ์‚ฌ์šฉ ํ™˜๊ฒฝ์— ๋งž์ถฐ ๋‹ค์–‘ํ•œ GC ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์ œ๊ณตํ•œ๋‹ค. ์ƒํ™ฉ์— ๋งž๋Š” ๋„๊ตฌ๋ฅผ ์„ ํƒํ•˜๋Š” ๊ฒƒ์ด ์„ฑ๋Šฅ ์ตœ์ ํ™”์˜ ์ง€๋ฆ„๊ธธ์ด ๋  ์ˆ˜ ์žˆ๋‹ค.

Serial GC & Parallel GC

  • Serial GC (-XX: +UseSerialGC)
    • GC ์Šค๋ ˆ๋“œ๊ฐ€ ๋”ฑ 1๊ฐœ๋‹ค.
    • ๊ตฌ์กฐ๊ฐ€ ๋‹จ์ˆœํ•˜์ง€๋งŒ GC๊ฐ€ ์ผ์–ด๋‚˜๋Š” ๋™์•ˆ STW ์‹œ๊ฐ„์ด ๊ธธ๋‹ค. (์ฒญ์†Œ๋ถ€๊ฐ€ 1๋ช…์ด๋ผ ์ฒญ์†Œํ•˜๋Š” ์‹œ๊ฐ„์ด ์˜ค๋ž˜ ๊ฑธ๋ฆผ)
    • CPU ์ฝ”์–ด๊ฐ€ 1๊ฐœ์ธ ํ™˜๊ฒฝ์ด๋‚˜ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์•„์ฃผ ์ ์€ ๊ฒฝ์šฐ์— ์ ํ•ฉํ•˜๋‹ค.
    • ์›น ์„œ๋ฒ„์™€ ๊ฐ™์ด ์ˆ˜๋งŽ์€ ์š”์ฒญ์„ ๋™์‹œ์— ์ฒ˜๋ฆฌํ•ด์•ผ ํ•˜๋Š” ํ™˜๊ฒฝ์ด ์•„๋‹Œ ํ˜ผ์ž ๋Œ์•„๊ฐ€๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด๋‚˜ ์ž ๊น ์‹คํ–‰๋˜๊ณ  ์ข…๋ฃŒ๋˜๋Š” ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜๊ณผ ๊ฐ™์ด ๋‹จ๋ฐœ์„ฑ CLIํˆด์ด๋‚˜ ๋ฐฐ์น˜ ํ”„๋กœ์„ธ์Šค์—์„œ ์‚ฌ์šฉํ•˜๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™๋‹ค.
  • Parallel GC (-XX: +UseParallelGC)
    • Java8์˜ ๋””ํดํŠธ GC๋‹ค.
    • Young ์˜์—ญ์˜ GC ์ž‘์—…์„ ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ณ‘๋ ฌ๋กœ ์ฒ˜๋ฆฌํ•œ๋‹ค. (Old ์˜์—ญ์€ ์„ค์ •์— ๋”ฐ๋ผ ๋‹ค๋ฆ„)
    • ์ฒ˜๋ฆฌ๋Ÿ‰์„ ์ค‘์‹œํ•˜๋Š” ๋ฐฐ์น˜ ์ž‘์—…์ด๋‚˜ ๋ฐ์ดํ„ฐ ๋ถ„์„ ์ž‘์—…์— ์œ ๋ฆฌํ•˜๋‹ค.

CMS GC (-XX: +UseConcMarkSweepGC)

  • STW ์‹œ๊ฐ„์„ ์ตœ์†Œํ™”ํ•˜๊ธฐ ์œ„ํ•ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰ ์ค‘์— ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ GC ์ž‘์—…์„ ๋™์‹œ์— ์ˆ˜ํ–‰ํ•œ๋‹ค.
  • ํ•˜์ง€๋งŒ CPU ์†Œ๋ชจ๊ฐ€ ๋งŽ๊ณ  ๋ฉ”๋ชจ๋ฆฌ ํŒŒํŽธํ™”๊ฐ€ ์ž์ฃผ ๋ฐœ์ƒํ•œ๋‹ค๋Š” ๋‹จ์ ์ด ์žˆ๋‹ค.
  • Java9 ๋ถ€ํ„ฐ๋Š” Deprecated ๋˜์—ˆ๊ณ , Java14์—์„œ ์™„์ „ํžˆ ์‚ญ์ œ๋๋‹ค.

G1(Garbage First) GC (-XX: +UseG1GC)

  • ํ˜„ ์‹œ์  ๊ฐ€์žฅ ๋งŽ์ด ์‚ฌ์šฉ๋˜๊ณ  ์žˆ๋Š” GC ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์ด๋‹ค.
  • Java9 ๋ถ€ํ„ฐ ํ˜„์žฌ(Java25) ๊นŒ์ง€ ๊ธฐ๋ณธ GC๋กœ ์‚ฌ์šฉ๋˜๊ณ  ์žˆ๋‹ค.
  • ์ด์ „์ฒ˜๋Ÿผ ํž™์„ ๋ฌผ๋ฆฌ์ ์ธ Young/Old ์˜์—ญ์œผ๋กœ ๋‚˜๋ˆ„์ง€ ์•Š๊ณ  Region์ด๋ผ๋Š” ์ž‘์€ ์‚ฌ๊ฐํ˜• ๋ธ”๋ก๋“ค๋กœ ๋ฐ”๋‘‘ํŒ์ฒ˜๋Ÿผ ์ชผ๊ฐ ๊ฒƒ์ด ํŠน์ง•์ด๋‹ค.
  • ๊ฐ Region์—๊ฒŒ Young์ด๋‚˜ Old ์—ญํ• ์„ ๋™์ ์œผ๋กœ ๋ถ€์—ฌํ•œ๋‹ค.
  • ์ด๋ฆ„ ์ฒ˜๋Ÿผ Garbage๊ฐ€ ๋งŽ์€ Region์„ ๋จผ์ €(First) ์ฒญ์†Œํ•˜์—ฌ ํšจ์œจ์ด ๋งค์šฐ ์ข‹๋‹ค.
  • ๋Œ€์šฉ๋Ÿ‰ ๋ฉ”๋ชจ๋ฆฌ์—์„œ๋„ ์˜ˆ์ธก ๊ฐ€๋Šฅํ•œ ์งง์€ ์ค‘๋‹จ ์‹œ๊ฐ„์„ ์ œ๊ณตํ•˜์—ฌ ์›น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ ๊ฐ€์žฅ ๊ถŒ์žฅ๋˜๋Š” ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‹ค.
  • Eden์„ ๋” ๋Š˜๋ฆฌ๋ฉด ๋‹ค์Œ GC์—์„œ Survivor / Promotion์„ ๊ฐ๋‹นํ•  ์ˆ˜ ์—†๋‹ค๊ณ  ํŒ๋‹จ๋  ๋•Œ GC๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.
  • Young GC๊ฐ€ ๋ฐœ์ƒํ•˜๋‹ค๊ฐ€ Old ์˜์—ญ์ด ์–ด๋А์ •๋„ ์Œ“์ด๋ฉด Mixed GC๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.

Region์˜ ํฌ๊ธฐ

G1GC์˜ Region์˜ ํฌ๊ธฐ๋Š” ๊ณ ์ •๋œ ํฌ๊ธฐ๊ฐ€ ์•„๋‹Œ ํž™ ํฌ๊ธฐ์— ๋”ฐ๋ผ ์ž๋™์œผ๋กœ ๊ฒฐ์ •๋œ๋‹ค.

  1. 2048๊ฐœ์˜ ๋ฒ•์น™
    • JVM์€ ์‹œ์ž‘ํ•  ๋•Œ ์ „์ฒด ํž™ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์•ฝ 2048๊ฐœ์˜ Region์œผ๋กœ ๋‚˜๋ˆ„๋ ค๊ณ  ์‹œ๋„ํ•œ๋‹ค.
      (Region Size = Total Heap Size / 2048)
  2. ๋ฒ”์œ„์˜ ์ œํ•œ
    • ๊ณ„์‚ฐ๋œ ๊ฐ’์ด ์•„๋ฌด๋ฆฌ ์ž‘๊ฑฐ๋‚˜ ์ปค๋„ Region์˜ ํฌ๊ธฐ๋Š” ๋ฐ˜๋“œ์‹œ ์ตœ์†Œ 1MB์—์„œ ์ตœ๋Œ€ 32MB ์‚ฌ์ด์—ฌ์•ผ ํ•œ๋‹ค.
  3. 2์˜ ๊ฑฐ๋“ญ์ œ๊ณฑ
    • ํฌ๊ธฐ๋Š” ๋ฐ˜๋“œ์‹œ 1, 2, 4, 8, 16, 32 MB์ค‘ ํ•˜๋‚˜์—ฌ์•ผ ํ•œ๋‹ค.
ํž™ ํฌ๊ธฐ(Xmx)๊ณ„์‚ฐ๋œ Region ์‚ฌ์ด์ฆˆ์‹ค์ œ Region ์‚ฌ์ด์ฆˆ
1 GB0.5 MB1 MB (์ตœ์†Œ๊ฐ’)
2 GB1 MB1 MB
4 GB2 MB2 MB
8 GB4 MB4 MB
16 GB8 MB8 MB
32 GB16 MB16 MB
64 GB ์ด์ƒ32 MB ์ด์ƒ32 MB (์ตœ๋Œ€๊ฐ’)

G1GC์˜ ๋™์ž‘ ์‚ฌ์ดํด

G1GC๋Š” ํฌ๊ฒŒ ๋‹ค์Œ 3๊ฐ€์ง€ ๋‹จ๊ณ„๋ฅผ ์ˆœํ™˜ํ•˜๋ฉฐ ๋™์ž‘ํ•œ๋‹ค.

  1. Young Only Phase (ํ‰์ƒ์‹œ ๋ชจ๋“œ)
    • ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์‹คํ–‰๋˜๋Š” ๋Œ€๋ถ€๋ถ„์˜ ์‹œ๊ฐ„ ๋™์•ˆ G1GC๋Š” ์ด ๋ชจ๋“œ์— ์žˆ๋‹ค.
      • ๋™์ž‘: ์˜ค์ง Young ์˜์—ญ(Eden + Survivor)๋งŒ ์ฒญ์†Œํ•œ๋‹ค.
      • ํŠน์ง•: Old ์˜์—ญ์€ ๊ฑด๋“œ๋ฆฌ์ง€ ์•Š๋Š”๋‹ค. ์ƒˆ๋กœ ์ƒ๊ธด ๊ฐ์ฒด๋งŒ ๋น ๋ฅด๊ฒŒ ์ฒญ์†Œํ•˜๊ณ , ์‚ด์•„๋‚จ์€ ๊ฐ์ฒด๋Š” Old ์˜์—ญ์œผ๋กœ Promotion ์‹œํ‚จ๋‹ค.
  2. Concurrent Marking Cycle (์ „ํ™˜ ์ค€๋น„ ๋‹จ๊ณ„)
    • Young GC๋งŒ ๊ณ„์†ํ•˜๋‹ค ๋ณด๋ฉด ์–ธ์  ๊ฐ€ Old ์˜์—ญ์— ๊ฐ์ฒด๊ฐ€ ์Œ“์ด๊ฒŒ ๋œ๋‹ค. Old ์˜์—ญ์˜ ์‚ฌ์šฉ๋Ÿ‰์ด ํŠน์ • ์ž„๊ณ„์น˜(๊ธฐ๋ณธ 45%)๋ฅผ ๋„˜์–ด์„œ๋ฉด G1GC๋Š” Old ์˜์—ญ ์ฒญ์†Œ ์ค€๋น„๋ฅผ ํ•œ๋‹ค.
      • ๋™์ž‘: ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰๊ณผ ๋™์‹œ์—(Concurrent) Old ์˜์—ญ์— ์žˆ๋Š” ๊ฐ์ฒด๋“ค ์ค‘ ์‚ด์•„์žˆ๋Š” ๊ฐ์ฒด๊ฐ€ ๋ฌด์—‡์ธ์ง€ ํŒŒ์•…(Marking) ํ•˜๊ธฐ ์‹œ์ž‘ํ•œ๋‹ค.
      • ํŠน์ง•: ์ด ๋•Œ๋„ Young GC๋Š” ๊ณ„์† ๋ฐœ์ƒํ•œ๋‹ค. Marking ์ž‘์—…์€ ๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ ์กฐ์šฉํžˆ ์ด๋ฃจ์–ด์ง„๋‹ค.
  3. Mixed GC Phase (๋Œ€์ฒญ์†Œ ๋ชจ๋“œ)
    • Marking์ด ๋๋‚˜์„œ ์–ด๋А Old Region์— ์“ฐ๋ ˆ๊ธฐ๊ฐ€ ๋งŽ์€์ง€ ํŒŒ์•…์ด ์™„๋ฃŒ๋˜๋ฉด Mixed GC ๋‹จ๊ณ„๋กœ ์ง„์ž…ํ•œ๋‹ค.
      • ๋™์ž‘: ๋ชจ๋“  Young ์˜์—ญ + ์“ฐ๋ ˆ๊ธฐ๊ฐ€ ๋งŽ์€ ์ผ๋ถ€ Old ์˜์—ญ์„ ํ•ฉ์ณ์„œ ๋™์‹œ์— ์ฒญ์†Œํ•œ๋‹ค.
      • ํŠน์ง•: ํ•œ ๋ฒˆ์˜ Mixed GC๋กœ ๋ชจ๋“  Old ์˜์—ญ์„ ๋‹ค ์น˜์šฐ๋Š”๊ฒŒ ์•„๋‹ˆ๋‹ค. ๋ชฉํ‘œํ•œ ๋งŒํผ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ํ™•๋ณด๋  ๋•Œ๊นŒ์ง€ ์—ฌ๋Ÿฌ ๋ฒˆ์˜ Mixed GC๋ฅผ ๋‚˜๋ˆ„์–ด ์ˆ˜ํ–‰ํ•œ๋‹ค.
      • ์ข…๋ฃŒ: ์ถฉ๋ถ„ํžˆ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ํ™•๋ณด๋˜๋ฉด ๋‹ค์‹œ Young Only Phase๋กœ ๋Œ์•„๊ฐ„๋‹ค.
1. ์ดˆ๊ธฐ์ƒํƒœ
ํž™ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์—ฌ๋Ÿฌ ๊ฐœ์˜ Region์œผ๋กœ ๋‚˜๋ˆ„์–ด์ ธ ์žˆ๋‹ค. ๊ฐ ์…€์˜ ์•ŒํŒŒ๋ฒณ์€ ํ•ด๋‹น Region์˜ ํ˜„์žฌ ์—ญํ• ์„ ๋‚˜ํƒ€๋‚ธ๋‹ค.

E: Eden Region
S: Suvivor Region
O: Old Region
ํฐ์ƒ‰E: ๋นˆ Region
2. Young GC
Eden ์˜์—ญ์ด ๊ฝ‰ ์ฐจ๋ฉด GC๊ฐ€ ๋ฐœ์ƒํ•œ๋‹ค.(Eden์„ ๋” ๋Š˜๋ฆฌ๋ฉด ๋‹ค์Œ GC์—์„œ Survivor / Promotion์„ ๊ฐ๋‹นํ•  ์ˆ˜ ์—†๋‹ค๊ณ  ํŒ๋‹จ๋  ๋•Œ)
์ด ๋•Œ Eden๊ณผ ์ผ๋ถ€ Survivor ์˜์—ญ์ด๋‚˜ Old์˜์—ญ์œผ๋กœ ๋ณต์‚ฌํ•˜๊ณ  ๋ณต์‚ฌ๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด ์›๋ž˜์˜ Region์€ Empty ์ƒํƒœ๊ฐ€ ๋œ๋‹ค. (์ด๋ฏธ์ง€์—์„œ S -> E๋กœ์˜ ํ™”์‚ดํ‘œ๋Š” ์ž˜๋ชป ํ‘œ๊ธฐ๋œ ๊ฒƒ์ด๋‹ˆ ๋ฌด์‹œํ•˜๊ธฐ ๋ฐ”๋ž€๋‹ค.)
3. Mixed GC(Young + Old ํšŒ์ˆ˜)
GC๊ฐ€ ์ˆ˜ํ–‰๋  ๋•Œ ์“ฐ๋ ˆ๊ธฐ๊ฐ€ ๊ฐ€์žฅ ๋งŽ์€ Old Region๋„ ํ•จ๊ป˜ ์„ ํƒํ•˜์—ฌ ์ฒญ์†Œํ•œ๋‹ค. (Mixed GC)
์ด๋ฅผ ํ†ตํ•ด ์ „์ฒด ํž™์„ ๋ฉˆ์ถ”๋Š” Major GC์˜ ๋นˆ๋„๋ฅผ ํš๊ธฐ์ ์œผ๋กœ ์ค„์ผ ์ˆ˜ ์žˆ๊ฒŒ ๋œ๋‹ค.
(์—ฌ๊ธฐ์„œ๋„ S -> E ๋ฐฉํ–ฅ์˜ ํ™”์‚ดํ‘œ๋Š” ์ž˜๋ชป ํ‘œ๊ธฐ๋œ ๊ฒƒ์ด๋‹ˆ ๋ฌด์‹œํ•˜๊ธฐ ๋ฐ”๋ž€๋‹ค.)

๊ฐ์ฒด๋Š” ํ•ญ์ƒ ๋‹ค๋ฆ„๊ณผ ๊ฐ™์€ ํ•œ ๋ฐฉํ–ฅ์œผ๋กœ ํ๋ฅธ๋‹ค.

  • New -> Eden (์ƒ์„ฑ)
  • Eden -> Survivor (์ƒ์กด, ์—ฌ๋Ÿฌ Survivor Region์œผ๋กœ ๋ถ„์‚ฐ๋˜์–ด ์ด๋™ํ•œ๋‹ค)
  • Survivor -> Survivor (๋˜ ์ƒ์กด, ์—ฌ๋Ÿฌ Survivor Region์œผ๋กœ ๋ถ„์‚ฐ๋˜์–ด ์ด๋™ํ•œ๋‹ค)
  • Survivor -> Old (์žฅ์ˆ˜, Promotion, ์—ฌ๋Ÿฌ Old Region์œผ๋กœ ๋ถ„์‚ฐ๋˜์–ด ์ด๋™ํ•œ๋‹ค)

ZGC (Z Garbage Collector) (-XX: +UseZGC)

  • G1GC ์ฒ˜๋Ÿผ ์ „์ฒด ํž™ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ž˜๊ฒŒ ์ชผ๊ฐœ์„œ ๊ด€๋ฆฌํ•˜๋Š” Region ๊ตฌ์กฐ๋ฅผ ๊ธฐ๋ฐ˜์œผ๋กœ ํ•œ๋‹ค.
  • Java11(์‹คํ—˜์ ), Java15(์ •์‹)๋ถ€ํ„ฐ ๋„์ž…๋œ ์ฐจ์„ธ๋Œ€ GC๋‹ค.
  • ๋ชฉํ‘œ: ํž™ ํฌ๊ธฐ๊ฐ€ ์ˆ˜ ํ…Œ๋ผ๋ฐ”์ดํŠธ(TB)๊ฐ€ ๋˜์–ด๋„ STW์‹œ๊ฐ„์„ 10ms ์ดํ•˜๋กœ ์œ ์ง€ํ•˜๋Š” ๊ฒƒ์ด ๋ชฉํ‘œ๋‹ค.
  • ์›๋ฆฌ: Colored Pointers(ํฌ์ธํ„ฐ์— ์ƒ‰๊น” ์ •๋ณด๋ฅผ ์ž…ํž˜)์™€ Load Barriers(๊ฐ์ฒด์„ ์ฝ์„ ๋•Œ ๋ผ์–ด๋“ค์–ด ์ฒ˜๋ฆฌ)๋ผ๋Š” ๊ณ ๊ธ‰ ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ•œ๋‹ค.
  • ํ˜„์žฌ OpenJDK ๊ณ„์—ด์—์„œ STW๋ฅผ ๊ฐ€์žฅ ์งง๊ณ  ์˜ˆ์ธก ๊ฐ€๋Šฅํ•˜๊ฒŒ ๋งŒ๋“  GC ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‹ค.
  • Low Latency(์ €์ง€์—ฐ)๊ฐ€ ์ƒ๋ช…์ธ ์‹ค์‹œ๊ฐ„ ์„œ๋น„์Šค์— ์ ํ•ฉํ•˜๋‹ค.
  • G1GC์— ๋น„ํ•ด์„œ CPU ์†Œ๋ชจ๊ฐ€ ๋” ๋งŽ๋‹ค.
  • 64bit ์‹œ์Šคํ…œ์—์„œ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•˜๋‹ค. (32bit ์‹œ์Šคํ…œ์€ ์‚ฌ์šฉ ๋ถˆ๊ฐ€)
  • ํ•ต์‹ฌ ํ‚ค์›Œ๋“œ๋Š” Colored Pointer, Load Barrier, Concurrent Reallocation ์ด๋‹ค.

ZGC๊ฐ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ค‘์ง€ ์—†์ด ์ˆ˜ํ–‰๋˜๋Š” ๋ฉ”์นด๋‹ˆ์ฆ˜

์•„๋ž˜ ๊ทธ๋ฆผ์€ ZGC๊ฐ€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์ค‘์ง€ ์—†์ด GC๊ฐ€ ์ผ์–ด๋‚  ์ˆ˜ ์žˆ๋Š”์ง€ ์„ค๋ช…ํ•˜๋Š” ๊ทธ๋ฆผ์ด๋‹ค.

1. Colored Pointer (ํฌ์ธํ„ฐ์— ์ƒ‰๊น” ์ž…ํžˆ๊ธฐ)
64bit ๊ฐ์ฒด ์ฐธ์กฐ ํฌ์ธํ„ฐ์˜ ์ƒ์œ„ ๋น„ํŠธ๋“ค์ด Color Bits๋กœ ์‚ฌ์šฉ๋œ๋‹ค. ์ด ๋น„ํŠธ๋“ค์€ ๊ฐ์ฒด๊ฐ€ ์‚ด์•„์žˆ๋Š”์ง€ (Marked0/1), ํ˜น์€ ์žฌ๋ฐฐ์น˜(์ด๋™) ๋˜์—ˆ๋Š”์ง€(Remapped)๋ฅผ ๋‚˜ํƒ€๋‚ธ๋‹ค. ์ด ์ •๋ณด๋ฅผ ํ†ตํ•ด ZGC๋Š” ๊ฐ์ฒด ์ฐธ์กฐ ํฌ์ธํ„ฐ๋งŒ ๋ณด๊ณ  ๊ฐ์ฒด์˜ ์ƒํƒœ๋ฅผ ์•Œ ์ˆ˜ ์žˆ๋‹ค.
2. Load Barrier (์ ‘๊ทผ ๊ฒ€๋ฌธ์†Œ)
์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์Šค๋ ˆ๋“œ๊ฐ€ ๊ฐ์ฒด์— ์ ‘๊ทผํ•˜๋ฉด Load Barrier๊ฐ€ ์ฐธ์กฐ ํฌ์ธํ„ฐ์˜ ์ƒ‰๊น”์„ ํ™•์ธํ•œ๋‹ค. ์ƒ‰๊น”์ด ์˜ฌ๋ฐ”๋ฅธ ์ƒํƒœ๋ผ๋ฉด ๋ฐ”๋กœ ํ†ต๊ณผ ํ•˜์—ฌ ๊ฐ์ฒด์— ์ ‘๊ทผํ•œ๋‹ค. ์ž˜๋ชป๋œ ์ƒํƒœ(์˜ˆ: GC๊ฐ€ ๊ฐ์ฒด๋ฅผ ์ด๋™์‹œํ‚ค๋Š” ์ค‘)๋ผ๋ฉด ์ž ์‹œ ๋ฉˆ์ถฐ ํฌ์ธํ„ฐ๋ฅผ ์˜ฌ๋ฐ”๋ฅด๊ฒŒ ๊ณ ์นœ ํ›„(Slow Path) ๊ฐ์ฒด์— ์ ‘๊ทผํ•œ๋‹ค.
3. Concurrent Relocation
๊ฐ์ฒด๊ฐ€ Old Region์—์„œ New Region์œผ๋กœ ์ด์‚ฌ๋ฅผ ๊ฐ”๋‹ค. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ์•„์ง Old Pointer(Bad Color)๋ฅผ ๊ฐ€์ง€๊ณ  ์ ‘๊ทผํ•˜๋ ค ํ•˜๋ฉด Load Barrier๊ฐ€ Forwarding Table(์ฃผ์†Œ๋ก)์„ ํ™•์ธํ•˜์—ฌ ์ƒˆ ์ฃผ์†Œ๋ฅผ ์ฐพ์•„๋‚ธ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ํฌ์ธํ„ฐ๋ฅผ New Pointer(Good Color)๋กœ ์—…๋ฐ์ดํŠธ ํ•œ ํ›„ ์ƒˆ ์œ„์น˜์˜ ๊ฐ์ฒด์— ์ ‘๊ทผํ•˜๊ฒŒ ํ•œ๋‹ค. ์ด ๋ชจ๋“  ๊ณผ์ •์ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ๋ฉˆ์ถค ์—†์ด ์•„์ฃผ ๋น ๋ฅด๊ฒŒ ์ผ์–ด๋‚œ๋‹ค.

ZGC๊ฐ€ STW๋ฅผ ๊ฐ€์žฅ ๋‹จ์ถ•ํ•  ์žˆ๋Š” GC์ธ๋ฐ ์™œ ๊ธฐ๋ณธ GC๋กœ ์‚ฌ์šฉํ•˜์ง€ ์•Š์„๊นŒ?

ZGC๋Š” STW๊ฐ€์žฅ ์ตœ์†Œํ™”ํ•  ์ˆ˜ ์žˆ๋Š” GC๋Š” ๋งž์ง€๋งŒ ์ผ๋ฐ˜์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ๋Š” ๋ฒ”์šฉ์  GC๊ฐ€ ์•„๋‹ˆ๋‹ค. G1GC๋Š” ์ค‘/๋Œ€ํ˜• ํž™ ํฌ๊ธฐ์—์„œ๋„ ๋น„๊ต์  ์•ˆ์ •์ ์œผ๋กœ ์‚ฌ์šฉํ•  ์ˆ˜ ์žˆ์ง€๋งŒ ZGC๋Š” ์ค‘ํ˜• ํž™ ํฌ๊ธฐ์—๋Š” ์ ๋‹นํ•˜์ง€ ์•Š์€ GC์•Œ๊ณ ๋ฆฌ์ฆ˜์ด๋‹ค. ์ฆ‰ ๋ฒ”์šฉ์ ์œผ๋กœ ์‚ฌ์šฉํ•˜๊ธฐ์—๋Š” G1GC์— ๋น„ํ•ด์„œ ๋ถ€์กฑํ•˜๊ธฐ ๋•Œ๋ฌธ์ด๋‹ค.

GC๊ด€๋ จ JVM ์˜ต์…˜

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰์‹œ ๊ด€๋ จ GC ๋กœ๊ทธ๋ฅผ ์ƒ์„ฑํ•˜๊ณ  GC ๋™์ž‘์— ํ•„์š”ํ•œ ๋ช‡๊ฐ€์ง€ ์˜ต์…˜๋“ค์ด ์žˆ๋‹ค.
Java 11์ด์ƒ ๋ถ€ํ„ฐ๋Š” -XX:+PrintGCDetails, -XX:+PrintGCTimeStamps์™€ ๊ฐ™์€ ์˜ต์…˜๋“ค์€ ํ๊ธฐ๋˜๊ณ  -Xlog ํ•˜๋‚˜๋กœ ํ†ตํ•ฉ๋˜์—ˆ๋‹ค.

-Xlog:gc*:file=/var/log/gc.log:time,uptime,level,tags:filecount=10,filesize=10M
Plaintext

์œ„ ์˜ต์…˜์€ GC๊ด€๋ จ ๋ชจ๋“  ๋กœ๊ทธ๋ฅผ /var/log/gc.log ํŒŒ์ผ์— ๊ธฐ๋กํ•˜๊ณ  ๋กœ๊ทธ ํŒŒ์ผ์—๋Š” ์‹œ๊ฐ„(time), JVM ์‹œ์ž‘ ํ›„ ๊ฒฝ๊ณผ ์‹œ๊ฐ„(uptime), ๋กœ๊ทธ ๋ ˆ๋ฒจ(level), ๋กœ๊ทธ๊ฐ€ ์–ด๋–ค ์˜์—ญ์—์„œ ๋‚˜์˜จ ๊ฒƒ์ธ์ง€(tag) ์ •๋ณด๋ฅผ ๊ธฐ๋กํ•œ๋‹ค. ๋˜ํ•œ ๋กœ๊ทธ ํŒŒ์ผ ๊ฐœ์ˆ˜๋Š” 10๊ฐœ๋กœ ์ œํ•œํ•˜๊ณ  ๋กœ๊ทธ ํŒŒ์ผ ์‚ฌ์ด์ฆˆ๋Š” 10M๋กœ ์ œํ•œํ•œ๋‹ค. ํŒŒ์ผ ํฌ๊ธฐ๊ฐ€ 10M๊ฐ€ ๋˜๋ฉด ์ž๋™์œผ๋กœ rotate ํ•œ๋‹ค.

๋‹ค์Œ์€ GC๊ด€๋ จ ์ฃผ์š” JVM ์˜ต์…˜ ํ‘œ๋‹ค. G1GC ๊ธฐ์ค€์œผ๋กœ ์ž‘์„ฑํ•˜์˜€๋‹ค.

์˜ต์…˜์„ค๋ช…๊ธฐ๋ณธ๊ฐ’
-Xmsํž™ ๋ฉ”๋ชจ๋ฆฌ์˜ ์ดˆ๊ธฐ ํฌ๊ธฐ์šด์˜์ฒด์ œ๋งˆ๋‹ค ๋‹ค๋ฆ„
-Xmxํž™ ๋ฉ”๋ชจ๋ฆฌ์˜ ์ตœ๋Œ€ ํฌ๊ธฐ๋ณดํ†ต Xms์™€ ๋™์ผํ•˜๊ฒŒ ์„ค์ •
-XX:+UseG1GC (+UseZGC)G1GC ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์‚ฌ์šฉJava 9์ด์ƒ ๊ธฐ๋ณธ ์•Œ๊ณ ๋ฆฌ์ฆ˜
-XX:MaxGCPauseMillisGC ์ตœ๋Œ€ ๋ฉˆ์ถค ์‹œ๊ฐ„ ๋ชฉํ‘œ ์„ค์ • (STW)G1GC ํŠœ๋‹์—์„œ ๊ฐ€์žฅ ์ค‘์š” (200ms)
-XX:NewRatioYoung:Old ์˜์—ญ ๋น„์œจ๊ธฐ๋ณธ 2 (Old๊ฐ€ Young์˜ 2๋ฐฐ)
-XX:SurvivorRatioEden:Survivor ์˜์—ญ ๋น„์œจ๊ธฐ๋ณธ 8 (Eden์ด Survivor์˜ 8๋ฐฐ)
-XX:G1HeapRegionSizeํž™์„ ๋‚˜๋ˆ„๋Š” region์˜ ํฌ๊ธฐ ์ง€์ • (1 ~ 32MB, 2์˜ ๊ฑฐ๋“ญ์ œ๊ณฑ)์ž๋™ ๊ณ„์‚ฐ๋˜์ง€๋งŒ ๊ณ ์ •ํ•  ์ˆ˜๋„ ์žˆ์Œ
-XX:InitiatingHeapOccupancyPercentOld ์˜์—ญ์ด ์ „์ฒด ํž™์˜ ๋ช‡ %๊ฐ€ ์ฐผ์„ ๋•Œ Mixed GC(Old ์˜์—ญ ์ฒญ์†Œ)๋ฅผ ์œ„ํ•œ marking์„ ์‹œ์ž‘ํ• ์ง€ ๊ฒฐ์ •45% (OOM์ด ๋ฐœ์ƒํ•˜๊ฑฐ๋‚˜ Old ์˜์—ญ์ด ๊ธ‰๊ฒฉํžˆ ์ฐฌ๋‹ค๋ฉด ์ด ๊ฐ’์„ ์ค„์—ฌ์„œ ๋ฏธ๋ฆฌ ์ฒญ์†Œํ•˜๊ฒŒ ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Œ)
-XX:G1NewSizePercentYoung ์˜์—ญ์˜ ์ตœ์†Œ ํฌ๊ธฐ ๋น„์œจ5%
-XX:G1MaxNewSizePercentYoung ์˜์—ญ์˜ ์ตœ๋Œ€ ํฌ๊ธฐ ๋น„์œจ60%
-XX:MaxTenuringThresholdOld ์˜์—ญ์œผ๋กœ ์ด๋™ํ•  Age ์„ค์ •15
-XX:+HeapDumpOnOutOfMemoryErrorOOM ์—๋Ÿฌ๊ฐ€ ๋ฐœ์ƒํ•ด์„œ ์„œ๋ฒ„๊ฐ€ ์ฃฝ์„ ๋•Œ ์ฃฝ๊ธฐ ์ง์ „์˜ ํž™ ๋ฉ”๋ชจ๋ฆฌ ์ƒํƒœ๋ฅผ hprof ํŒŒ์ผ๋กœ ๋คํ”„๋ฅผ ๋œฌ๋‹ค.OOM ๋ฐœ์ƒ์‹œ ์›์ธ ํŒŒ์•…์„ ์œ„ํ•œ ์ค‘์š”ํ•œ ์ž๋ฃŒ๊ฐ€ ๋œ๋‹ค. (ํ•„์ˆ˜๋กœ ์ง€์ •)
-XX:HeapDumpPathํž™ ๋คํ”„ ํŒŒ์ผ์˜ ๊ฒฝ๋กœ ์ง€์ •๊ธฐ๋ณธ์ ์œผ๋กœ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‹คํ–‰ํ•œ ๋””๋ ‰ํ† ๋ฆฌ์— ์ƒ์„ฑ๋˜๋‚˜ ํž™ ๋คํ”„ ํŒŒ์ผ์˜ ์‚ฌ์ด์ฆˆ๊ฐ€ ํฌ๋‹ค๋Š” ๊ฒƒ์„ ๊ฐ์•ˆํ•˜์—ฌ ๋””์Šคํฌ ํฌ๊ธฐ๊ฐ€ ์—ฌ์œ ์žˆ๋Š” ๋””๋ ‰ํ† ๋ฆฌ๋กœ ์ง€์ •์„ ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Œ.
-XX:MetaspaceSizeํž™์ด ์•„๋‹Œ Metaspace ํด๋ž˜์Šค ์ •๋ณด ์ €์žฅ ๊ณต๊ฐ„์˜ ์ตœ๋Œ€ ํฌ๊ธฐ๋ฅผ ์ œํ•œ์•ฝ 21MB (128~256MB ์ •๋„ ์„ค์ • ๊ถŒ์žฅ)
-XX:+DisableExplicitGC์ฝ”๋“œ์ƒ์˜ System.gc() ํ˜ธ์ถœ์„ ๋ฌด์‹œํ•˜๋Š” ์˜ต์…˜false
-XX:ParallelGCThreads์ฒญ์†Œํ•  ์Šค๋ ˆ๋“œ ๊ฐœ์ˆ˜CPU ์ฝ”์–ด ์ˆ˜์— ๋”ฐ๋ผ ๊ฒฐ์ •
(์ฝ”์–ด ์ˆ˜๊ฐ€ ๋งŽ๋‹ค๊ณ  ๋ฌด์ž‘์ • 1:1๋กœ ๋Š˜๋ฆฌ๋ฉด ์Šค๋ ˆ๋“œ ๊ฐ„ ๋™๊ธฐํ™” ์˜ค๋ฒ„ํ—ค๋“œ๊ฐ€ ์ปค์ง€๋ฏ€๋กœ 8๊ฐœ ์ด์ƒ ๋ถ€ํ„ฐ๋Š” ์ฆ๊ฐ€ํญ์„ ์ค„์ด๋Š” ๊ฒƒ์ด ์ข‹์Œ)
-XX:ConcGCThreads๋ฐฑ๊ทธ๋ผ์šด๋“œ์—์„œ Marking ์ž‘์—…์„ ์ˆ˜ํ–‰ํ•  ์Šค๋ ˆ๋“œ ์ˆ˜ParallelGCThreads ์ˆ˜์น˜์˜ 1/4

JVM์˜ ๊ธฐ๋ณธ๊ฐ’์„ ํ™•์ธํ•˜๊ณ ์ž ํ•  ๋•Œ ๋‹ค์Œ ๋ช…๋ น์ด ๋„์›€์ด ๋  ์ˆ˜ ์žˆ๋‹ค.
java -XX:+PrintFlagsFinal -version

GC ๋™์ž‘ ์‹œ๋ฎฌ๋ ˆ์ด์…˜

์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์—์„œ GC ๋™์ž‘์— ๋Œ€ํ•ด์„œ ์‹œ๊ฐ์ ์œผ๋กœ ์–ด๋–ป๊ฒŒ ๋™์ž‘ํ•˜๋Š”์ง€ ์‚ดํŽด๋ณด์ž.
์ƒ˜ํ”Œ ์ฝ”๋“œ๋Š” while loop ๋‚ด์—์„œ 100KB byte ๋ฐฐ์—ด ์ธ์Šคํ„ด์Šค๋ฅผ ์ƒ์„ฑ๋งŒ ํ•˜๋„๋ก ํ•˜๋Š” ๋ณ€์ˆ˜๊ฐ€ ์žˆ๊ณ  loop์ด 100๋ฒˆ ์ˆ˜ํ–‰๋  ๋•Œ๋งˆ๋‹ค static List์— 100KB ํฌ๊ธฐ์˜ byte ๋ฐฐ์—ด์„ ์ €์žฅํ•˜๋„๋ก ํ–ˆ๋‹ค. ์‹œ๊ฐ„์ด ์ง€๋‚  ์ˆ˜๋ก static List์—๋Š” 100KB byte ๋ฐฐ์—ด์ด ๋ˆ„์ ๋˜์„œ ์Œ“์ผ ๊ฒƒ์ด๊ณ  static List์— 5000๊ฐœ(500MB) ๊ฐ€ ์Œ“์ด๋ฉด List๋ฅผ clear ํ•˜๋„๋ก ํ–ˆ์„ ๋•Œ G1GC์˜ GC ๊ทธ๋ž˜ํ”„๋Š” ์–ด๋–ป๊ฒŒ ๋˜๋Š”์ง€ ์‚ดํŽด๋ณด์ž. JVM ํž™ ๋ฉ”๋ชจ๋ฆฌ๋Š” 512MB๋ฅผ ์„ค์ •ํ•˜์˜€๋‹ค.

GC ๋™์ž‘์— ๋Œ€ํ•œ ์‹œ๊ฐํ™”๋Š” VisualVM์„ ์‚ฌ์šฉํ•˜์˜€๋‹ค. VisualVM์—์„œ GC๋™์ž‘์„ ์‹œ๊ฐํ™”ํ•˜์—ฌ ํ™•์ธํ•˜๋ ค๋ฉด VisualVM์—์„œ VisualGC ํ”Œ๋Ÿฌ๊ทธ์ธ์„ ์„ค์น˜ํ•˜๋ฉด ๋œ๋‹ค.
VisualVM ์‹คํ–‰ > Tools > Plugins > Available Plugins > VisualGC
ํ…Œ์ŠคํŠธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์‹คํ–‰ํ•˜๋ฉด VisualVM ์ขŒ์ธก ๋ฉ”๋‰ด Local ํ•ญ๋ชฉ์— ์‹คํ–‰ํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด pid์™€ ํ•จ๊ป˜ ๋ชฉ๋ก์— ๋‚˜ํƒ€๋‚œ๋‹ค. ํ•ด๋‹น ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ์„ ํƒํ•˜์—ฌ ์ƒ๋‹จ์˜ VisualGC ํƒญ์„ ์„ ํƒํ•˜๋ฉด GC๋™์ž‘์„ ์‹œ๊ฐํ™”ํ•˜์—ฌ ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

์ƒ˜ํ”Œ์ฝ”๋“œ

public class GCLoadTest {
    // Old ์˜์—ญ์œผ๋กœ ๋„˜์–ด๊ฐˆ ๊ฐ์ฒด๋“ค์„ ๋‹ด์„ ๋ฆฌ์ŠคํŠธ (๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜ ์‹œ๋ฎฌ๋ ˆ์ด์…˜)
    private static List<byte[]> oldGenList = new ArrayList<>();

    public static void main( String[] args ) throws InterruptedException {
        System.out.println("Start GC Load Test ...");

        int loopCount = 0;
        while ( true ) {
            // 1. Eden ์˜์—ญ์— ํ• ๋‹น๋  ์งง์€ ์ƒ๋ช…์ฃผ๊ธฐ ๊ฐ์ฒด (100KB) - ์ˆ˜๊ฑฐ ๋Œ€์ƒ
            byte[] shortLived = new byte[100 * 1024];

            // 2. ๊ฐ€๋”์”ฉ Old ์˜์—ญ์œผ๋กœ promotion๋  ๊ฐ์ฒด ์ €์žฅ
            // 100 ๋ฃจํ”„๋งˆ๋‹ค 100KB์”ฉ Old ๋Œ€์ƒ ์ƒ์„ฑ
            if( loopCount % 100 == 0 ) {
                oldGenList.add( new byte[100 * 1024] );

                if ( oldGenList.size() % 100 == 0 ) {
                    System.out.println("Total retained count: " + oldGenList.size() );
                    System.out.println("Total retained size: " + ( oldGenList.size() * 100 / 1024 ) + "MB");
                    System.out.println("=============================");
                }
            }

            // 3. OOM ๋ฐฉ์ง€์šฉ sleep
            Thread.sleep( 2 );
            loopCount++;

            // Old ์˜์—ญ ๊ณผ๋„ํ•œ ์ฆ๊ฐ€ ๋ฐฉ์ง€ (ํ…Œ์ŠคํŠธ์šฉ์œผ๋กœ 500MB๊ฐ€ ์ฐจ๋ฉด ๋น„์›€)
            if ( oldGenList.size() > 5000 ) {
                oldGenList.clear();
                System.out.println("Cleared old gen list. (Released Memory)");
            }
        }
    }
}
Java

์œ„ ์ฝ”๋“œ๋ฅผ ์ปดํŒŒ์ผํ•˜๊ณ  ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์‹คํ–‰ํ•ด๋ณด์ž.

java -Xms512m -Xmx512m -XX:+UseG1GC \
-XX:MaxGCPauseMillis=200 \
-Xlog:"gc*:file=gc.log:time,uptime,level,tags" \
GCLoadTest
Bash

gc.log ํŒŒ์ผ์˜ ์ฒซ ๋ถ€๋ถ„์„ ๋ณด๋ฉด ๋‹ค์Œ๊ณผ ๊ฐ™์€ ๋‚ด์šฉ์ด ์žˆ๋‹ค.

[2025-12-28T00:03:47.682+0900][0.012s][info][gc,heap] Heap region size: 1M
[2025-12-28T00:03:47.683+0900][0.013s][info][gc     ] Using G1
[2025-12-28T00:03:47.683+0900][0.013s][info][gc,heap,coops] Heap address: 0x00000007a0000000, size: 512 MB, Compressed Oops mode: Zero based, Oop shift amount: 3
Plaintext

‘Heap region size: 1M’: Heap region ํฌ๊ธฐ๋Š” 1MB (xmx 512MB ํž™ ํฌ๊ธฐ์— ๋Œ€ํ•œ region ํฌ๊ธฐ๋Š” 1MB๋‹ค.)
‘Using G1’์„ ํ†ตํ•ด์„œ G1GC ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์‚ฌ์šฉํ•œ๋‹ค๋Š” ๊ฒƒ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

์ฒซ๋ฒˆ์งธ GC๋กœ๊ทธ๋ฅผ ์‚ดํŽด๋ณด์ž.

[2025-12-28T00:03:48.341+0900][0.671s][info][gc,start     ] GC(0) Pause Young (Normal) (G1 Evacuation Pause)
[2025-12-28T00:03:48.341+0900][0.672s][info][gc,task      ] GC(0) Using 9 workers of 9 for evacuation
[2025-12-28T00:03:48.343+0900][0.673s][info][gc,phases    ] GC(0)   Pre Evacuate Collection Set: 0.0ms
[2025-12-28T00:03:48.343+0900][0.673s][info][gc,phases    ] GC(0)   Evacuate Collection Set: 1.5ms
[2025-12-28T00:03:48.343+0900][0.673s][info][gc,phases    ] GC(0)   Post Evacuate Collection Set: 0.2ms
[2025-12-28T00:03:48.343+0900][0.673s][info][gc,phases    ] GC(0)   Other: 0.7ms
[2025-12-28T00:03:48.343+0900][0.674s][info][gc,heap      ] GC(0) Eden regions: 25->0(306)
[2025-12-28T00:03:48.343+0900][0.674s][info][gc,heap      ] GC(0) Survivor regions: 0->1(4)
[2025-12-28T00:03:48.343+0900][0.674s][info][gc,heap      ] GC(0) Old regions: 0->0
[2025-12-28T00:03:48.343+0900][0.674s][info][gc,heap      ] GC(0) Humongous regions: 0->0
Plaintext

๊ฐ ๋กœ๊ทธ๋ฅผ ํ•œ์ค„์”ฉ ํŒŒ์•…ํ•ด๋ณด์ž.

Using 9 workers of 9 for evacuation
์ด 9๊ฐœ์˜ GC ์Šค๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ๋ณ‘๋ ฌ๋กœ ์ž‘์—…์„ ์ฒ˜๋ฆฌํ•จ.

์ด GC ์ˆ˜ํ–‰ ์‹œ๊ฐ„์€ ๋‹ค์Œ๊ณผ ๊ฐ™์ด ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.
Pre Evacuate Collection Set: 0.0ms: ๊ฐ์ฒด๋ฅผ ์˜ฎ๊ธฐ๊ธฐ ์ „ ์ฒญ์†Œํ•  ๋ฆฌ์ „์„ ๊ณ ๋ฅด๋Š” ์‹œ๊ฐ„
Evacuate Collection Set: 1.5ms: ์‹ค์ œ๋กœ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ •๋ฆฌํ•˜๋Š” ์‹œ๊ฐ„
Post Evacuate Collection Set: 0.2ms: ์ด์‚ฌ ํ›„ ์ •๋ฆฌ ์‹œ๊ฐ„
Other: 0.7ms: ๊ทธ ์™ธ ์ž์ž˜ํ•œ ์ž‘์—… ์‹œ๊ฐ„ (์ด ์‹œ๊ฐ„์ด ๋น„์ •์ƒ์ ์œผ๋กœ ๊ธธ๋‹ค๋ฉด OS๋ฌธ์ œ๋‚˜ ๊ฐ€์ƒํ™” ํ™˜๊ฒฝ ๋ฌธ์ œ๋ฅผ ์˜์‹ฌํ•ด ๋ณผ์ˆ˜ ์žˆ์Œ)
์ด GC์— ์†Œ์š”๋œ ์‹œ๊ฐ„ = STW ์‹œ๊ฐ„ = 2.4ms

Eden regions: 25 -> 0(306)
25๊ฐœ์˜ Eden region์ด ๋ชจ๋‘ ๋น„์›Œ์ ธ 0๊ฐœ๊ฐ€ ๋˜์—ˆ๋‹ค๋Š” ์˜๋ฏธ.

(306)๊ณผ ๊ฐ™์ด ๊ด„ํ˜ธ ์•ˆ์˜ ๊ฐ’์€ ๋‹ค์Œ GC๊ฐ€ ์ˆ˜ํ–‰๋  ๋•Œ๊นŒ์ง€ ์ฑ„์›Œ์งˆ Eden region์˜ ๋ชฉํ‘œ ๊ฐœ์ˆ˜๋ฅผ ์˜๋ฏธํ•œ๋‹ค. ์•ž์„  ์‹คํ–‰ ์˜ต์…˜์—์„œ -XX:MaxPauseMillis=200์œผ๋กœ ์ง€์ •ํ–ˆ๋Š”๋ฐ 25๊ฐœ์˜ region์„ ์ฒญ์†Œํ•˜๋Š”๋ฐ 2.4ms ๋ฐ–์— ๊ฑธ๋ฆฌ์ง€ ์•Š์•˜๊ธฐ ๋•Œ๋ฌธ์— ๋ชฉํ‘œ ์‹œ๊ฐ„ 200ms์— ๋งž์ถ”๋ ค๊ณ  ์ฒญ์†Œํ•  region ๊ฐœ์ˆ˜๋ฅผ ๋” ๋Š˜๋ฆฐ ๊ฒƒ์ด๋ผ๊ณ  ๋ณด๋ฉด ๋˜๊ฒ ๋‹ค.

Survivor regions: 0 -> 1(4)
GC์ „ Survivor ์˜์—ญ์€ ๋น„์–ด์žˆ๊ณ  GC ํ›„ ์‚ด์•„๋‚จ์€ ๊ฐ์ฒด๋“ค์ด 1๊ฐœ์˜ Survivor ๋ฆฌ์ „์œผ๋กœ ์ด๋™ํ–ˆ๋‹ค๋Š” ์˜๋ฏธ.

(4)์™€ ๊ฐ™์ด ๊ด„ํ˜ธ ์•ˆ์˜ ๊ฐ’์€ ๋‹ค์Œ์— 306๊ฐœ์˜ Eden region์„ ์ •๋ฆฌํ•  ๋•Œ ์‚ด์•„๋‚จ๋Š” ๊ฐ์ฒด๋ฅผ ์˜ˆ์ƒํ•˜์—ฌ ๋ฏธ๋ฆฌ survivor region์„ ๋น„์›Œ๋‘๊ธฐ ์œ„ํ•œ ์˜ˆ์•ฝ ๊ฐœ์ˆ˜๋ผ๊ณ  ๋ณด๋ฉด ๋˜๊ฒ ๋‹ค.
(Survivor ์˜์—ญ์ด 4๊ฐœ๊ฐ€ ๋  ๋•Œ๊นŒ์ง€ ๊ธฐ๋‹ค๋ฆฌ๋Š” ๊ฒƒ์ด ์•„๋‹ˆ๋‹ค. GC๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๋•Œ ์‚ด์•„๋‚จ์€ ๊ฐ์ฒด๋ฅผ ์ด๋™ํ•˜๋Š” Survivor region์ด 1๊ฐœ๋งŒ ์‚ฌ์šฉ๋˜๋ฉด 1๊ฐœ๋งŒ ์‚ฌ์šฉํ•˜๋Š” ๊ฒƒ์ด๊ณ , 4๊ฐœ๊ฐ€ ๋„˜์น˜๋„๋ก ๊ฐ์ฒด๋“ค์ด ์‚ด์•„๋‚จ๋Š” ๋‹ค๋ฉด ๊ทธ ๋•Œ๋Š” Old ์˜์—ญ์œผ๋กœ ๋„˜๊ธด๋‹ค.)

Old regions: 0 -> 0
์ƒ์„ฑ๋œ old region์€ ์—†์Œ์„ ์˜๋ฏธ.

์ด๋ฒˆ์—” oldGenList ๋ฆฌ์ŠคํŠธ์˜ ๊ฐœ์ˆ˜๊ฐ€ ๊ฑฐ์˜ 5000๊ฐœ์— ์œก๋ฐ•ํ•  ์‹œ์ ์˜ GC๋กœ๊ทธ๋ฅผ ์‚ดํŽด๋ณด์ž.

[2025-12-28T00:24:49.524+0900][1261.901s][info][gc,start       ] GC(1510) Pause Young (Normal) (G1 Evacuation Pause)
[2025-12-28T00:24:49.524+0900][1261.901s][info][gc,task        ] GC(1510) Using 9 workers of 9 for evacuation
[2025-12-28T00:24:49.525+0900][1261.901s][info][gc,phases      ] GC(1510)   Pre Evacuate Collection Set: 0.0ms
[2025-12-28T00:24:49.525+0900][1261.901s][info][gc,phases      ] GC(1510)   Evacuate Collection Set: 0.4ms
[2025-12-28T00:24:49.525+0900][1261.901s][info][gc,phases      ] GC(1510)   Post Evacuate Collection Set: 0.1ms
[2025-12-28T00:24:49.525+0900][1261.901s][info][gc,phases      ] GC(1510)   Other: 0.1ms
[2025-12-28T00:24:49.525+0900][1261.901s][info][gc,heap        ] GC(1510) Eden regions: 1->0(25)
[2025-12-28T00:24:49.525+0900][1261.901s][info][gc,heap        ] GC(1510) Survivor regions: 0->0(4)
[2025-12-28T00:24:49.525+0900][1261.901s][info][gc,heap        ] GC(1510) Old regions: 511->511
[2025-12-28T00:24:49.525+0900][1261.901s][info][gc,heap        ] GC(1510) Humongous regions: 0->0
Plaintext

Old regions: 511 -> 511
Old region์ด 511๊ฐœ๋กœ ๊ฑฐ์˜ ๋Œ€๋ถ€๋ถ„์˜ ํž™์„ ์ฐจ์ง€ํ•˜๊ณ  ์žˆ๋‹ค.

Survivor regions: 0 -> 0
Survivor region์€ 0๊ฐœ๋กœ ์•„๋งˆ๋„ ์ด ์‹œ์ ์—๋Š” Survivor์„ ๊ฑฐ์น˜์ง€ ์•Š๊ณ  ๋ฐ”๋กœ Old region์œผ๋กœ ๊ฐ์ฒด๊ฐ€ ์ด๋™ํ•˜๊ณ  ์žˆ๋Š” ๊ฒƒ์œผ๋กœ ๋ณด์ธ๋‹ค.

์ˆ˜ํ–‰ ์‹œ๊ฐ„์€ ์ดˆ 0.6ms ๋ฐ–์— ๊ฑธ๋ฆฌ์ง€ ์•Š์•˜์ง€๋งŒ ์ด๋Š” ์•„๋งˆ๋„ Old region์ด ๋Œ€๋ถ€๋ถ„์˜ ํž™์„ ์ฐจ์ง€ํ•˜๊ณ  ์žˆ์œผ๋ฏ€๋กœ ์‚ฌ์šฉ๊ฐ€๋Šฅํ•œ Eden region์ด ์ƒ๋‹นํžˆ ๋ถ€์กฑํ–ˆ์„ ๊ฒƒ์ด๋‹ค. ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น์„ ํ•˜๊ธฐ ์œ„ํ•ด์„œ GC๊ฐ€ ๋งค์šฐ ๋นˆ๋ฒˆํ•˜๊ฒŒ ๋ฐœ์ƒํ–ˆ์„ ๊ฒƒ์œผ๋กœ ์˜ˆ์ƒ๋œ๋‹ค. ์‹ค์ œ๋กœ ์ด ์‹œ์ ์˜ GC๋กœ๊ทธ๋ฅผ ๋ณด๋ฉด 1์ดˆ ์•ˆ์—์„œ ์‰ฌ์ง€์•Š๊ณ  ๊ณ„์† GC๊ฐ€ ๋ฐœ์ƒํ•จ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค. ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์„ฑ๋Šฅ์ด ์ƒ๋‹นํžˆ ์ €ํ•˜๋œ ์‹œ์ ์ด๋ผ๊ณ  ๋ณผ ์ˆ˜ ์žˆ๋‹ค.

VisualVM์˜ VisualGC๋ฅผ ํ†ตํ•œ GC ๊ทธ๋ž˜ํ”„๋Š” ๋‹ค์Œ๊ณผ ๊ฐ™๋‹ค.

๋ถ‰์€์ƒ‰ ๋„ค๋ชจ ์˜์—ญ์ด oldGenList๊ฐ€ clear()๋œ ์‹œ์ ์ด๋‹ค. ์ดˆ๋ฐ˜์˜ GC๊ทธ๋ž˜ํ”„๊ฐ€ ์งค๋ ค์„œ ๊ทธ๋ ‡์ง€ ์ดˆ๋ฐ˜์˜ ๊ทธ๋ž˜ํ”„๋Š” ๋ถ‰์€์ƒ‰ ๋„ค๋ชจ ์˜์—ญ(๋ฉ”๋ชจ๋ฆฌ ์ดˆ๊ธฐํ™” ์‹œ์ )๊ณผ ๊ฑฐ์˜ ๋™์ผํ•˜๋‹ค๊ณ  ๋ณด๋ฉด ๋œ๋‹ค.
๊ทธ๋ž˜ํ”„๋ฅผ ๋ณด๋ฉด ์•Œ ์ˆ˜ ์žˆ๋“ฏ์ด oldGenList์— ๋ฐ์ดํ„ฐ๊ฐ€ ์Œ“์ผ ์ˆ˜๋ก Eden๊ณผ Survivor region์˜ ๊ฐœ์ˆ˜๋Š” ์ ์  ์ž‘์–ด์ง€๊ณ  Old region์˜ ๊ฐœ์ˆ˜๊ฐ€ ์ ์  ๋Š˜์–ด๋‚˜๋Š” ๊ฒƒ์„ ๋ณผ ์ˆ˜ ์žˆ๋‹ค. clear๋ฅผ ํ•˜์ง€ ์•Š์•˜๋‹ค๋ฉด OutOfMemoryError๊ฐ€ ๋ฐœ์ƒํ–ˆ์„ ๊ฒƒ์ด๋‹ค.

VisualVM์˜ Sampler ํƒญ์„ ๋ณด๋ฉด ์–ด๋–ค ํƒ€์ž…์—์„œ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋Š”์ง€ ํ™•์ธํ•  ์ˆ˜ ์žˆ๋‹ค.

Sampler ํž™ ๋ฉ”๋ชจ๋ฆฌ์™€ ์Šค๋ ˆ๋“œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ†ตํ•ด์„œ ๋Œ€์ถฉ ์–ด๋””์—์„œ ๋ˆ„์ˆ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋Š”์ง€ ์ง์ž‘ํ•  ์ˆ˜ ์žˆ๋‹ค.
Sampler – ํž™ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๋ณด๋ฉด byte[] ๋ฐฐ์—ด์— ๋Œ€๋ถ€๋ถ„์˜ ํž™ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ํ• ๋‹น๋˜๊ณ  ์žˆ์Œ์„ ํ™•์ธํ•  ์ˆ˜ ์žˆ๊ณ  ์Šค๋ ˆ๋“œ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๋ณด๋ฉด main ์Šค๋ ˆ๋“œ์—์„œ ๋Œ€๋ถ€๋ถ„์˜ ํž™ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์‚ฌ์šฉํ•˜๊ณ  ์žˆ์Œ์„ ์•Œ ์ˆ˜ ์žˆ๋‹ค.
์‹ค์ œ ์šด์˜ ํ™˜๊ฒฝ์—์„œ๋Š” OutOfMemoryError์— ๋Œ€ํ•ด์„œ gc ๋กœ๊ทธ ํŒŒ์ผ๊ณผ ํž™ ๋คํ”„ ํŒŒ์ผ์„ VisualVM์— ์ž…๋ ฅํ•˜์—ฌ ๋ถ„์„ํ•˜๋Š” ๊ฒƒ์ด ๋งŽ์€ ๋„์›€์ด ๋  ๊ฒƒ์ด๋‹ค.


์ง€๊ธˆ๊นŒ์ง€ GC์— ๋Œ€ํ•œ ๋‚ด์šฉ์„ ์ •๋ฆฌํ•ด ๋ดค๋‹ค.
GC ๋กœ๊ทธ๋ฅผ ๋ถ„์„ํ•ด ๋ณธ ์ ๋„ ์—†๊ณ  ๋ง‰์—ฐํžˆ GC๊ฐ€ ์ค‘์š”ํ•œ ๋ถ€๋ถ„์ด๋ผ๊ณ  ์ƒ๊ฐ๋งŒํ•˜๊ณ  ์žˆ์—ˆ์ง€ ์„ธ์„ธํ•˜๊ฒŒ ์•Œ๊ณ  ์žˆ์ง€๋Š” ์•Š์•˜๋‹ค. ์ด๋ฒˆ ํฌ์ŠคํŒ…์„ ์ž‘์„ฑํ•˜๋ฉด์„œ GC์— ๋Œ€ํ•ด์„œ ๋ณธ์ธ์ด ๊ฐ€์žฅ ๋งŽ์ด ๋ฐฐ์šด ๊ฒƒ ๊ฐ™๋‹ค.
์ด ํฌ์ŠคํŒ…์„ ํ†ตํ•ด์„œ ๊ฐœ๋ฐœํ•˜๋Š” ์„œ๋น„์Šค๊ฐ€ ๋” ์•ˆ์ •์ ์ด๊ณ  ๋น ๋ฅด๊ฒŒ ๋™์ž‘ํ•˜๋„๋ก ํ•˜๋Š”๋ฐ ๋„์›€์ด ๋˜๊ธธ ๋ฐ”๋ž€๋‹ค.

์ฐธ๊ณ  ์‚ฌ์ดํŠธ

https://newrelic.com/blog/apm/java-garbage-collection
https://medium.com/@khurshidbek-bakhromjonov/java-memory-management-understanding-the-jvm-heap-method-area-stack-24a4d4fa2363
https://www.ibm.com/think/topics/garbage-collection-java
https://www.baeldung.com/jvm-static-storage