Programming/Java

F008 - Garbage Collector

osean 2021. 5. 16. 16:49
โœ๏ธ ์ €๋ฒˆ ์‹œ๊ฐ„์— ๊ณต๋ถ€ํ–ˆ๋˜ JVM ๋‚ด์šฉ๊ณผ ์—ฐ๊ฒฐ๋˜๋Š” ์ด์œ ๋กœ Garbage Collector(์ดํ•˜ GC)์— ๋Œ€ํ•ด ๊ณต๋ถ€ํ•ด๋ณด๋ ค๊ณ  ํ•œ๋‹ค.

Reference Type ๊ณผ Heap Memory๋ฅผ ๊ณต๋ถ€ํ•˜๋ฉด์„œ Heap Memory ๋‚ด์— ์กด์žฌํ•˜๋Š” ๊ฐ์ฒด๋ฅผ ์ฐธ์กฐํ•˜๋Š” ๊ณณ์ด ์—†์„ ๋•Œ GC๊ฐ€ ์ด๋ฅผ ์ฒ˜๋ฆฌํ•ด์ค€๋‹ค๋Š” ๊ฒƒ์€ ์กฐ๊ธˆ์ด๋‚˜๋งˆ ์ดํ•ดํ–ˆ๋‹ค. ๊ทธ๋ ‡๋‹ค๋ฉด ์–ด๋–ค ์‹œ์ ์—, ์–ด๋–ค ๋ฐฉ๋ฒ•์œผ๋กœ GC๋Š” ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ •๋ฆฌํ•ด์ฃผ๋Š”๊ฑธ๊นŒ?

์ด๋ฒˆ ์‹œ๊ฐ„์„ ํ†ตํ•ด ์•Œ์•„๋ณด์ž!

Un-Managed Language, Managed Language

๋งŽ์€ ํ”„๋กœ๊ทธ๋ž˜๋ฐ ์–ธ์–ด๋“ค์€ Mangaed Language, Un-Managed Language ๋กœ ๋‚˜๋‰˜์–ด ๊ตฌ๋ถ„๋  ์ˆ˜ ์žˆ๋‹ค. ์ด ๋‘˜์˜ ์˜๋ฏธ๋Š” ๋ฌด์—‡์„ ๋œปํ•˜๋Š”๊ฑธ๊นŒ? ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ด€์—ฌํ•ด์•ผ ํ•œ๋‹ค๋ฉด Un-Managed Language, ๊ด€์—ฌํ•˜์ง€ ์•Š์•„๋„ ์•Œ์•„์„œ ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ์ตœ์ ํ™”๊ฐ€ ์ง„ํ–‰๋œ๋‹ค๋ฉด Managed Language ๋ผ๊ณ  ํ•œ๋‹ค.

Un-Managed Language

C, Cpp, Assembly ๋“ฑ์ด ์—ฌ๊ธฐ์— ์†ํ•œ๋‹ค. ํ•ด๋‹น ์˜์—ญ์˜ ์–ธ์–ด๋“ค์€ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ ๋ฉ”๋ชจ๋ฆฌ๋‚˜ CPU์— ์ ‘๊ทผํ•ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์ตœ์ ํ™”๋ฅผ ๊ธฐ๋Œ€ ํ•  ์ˆ˜ ์žˆ๋‹ค. ํ•˜์ง€๋งŒ ์˜ˆ์ƒ์น˜ ๋ชปํ•˜๊ฒŒ ๋ฉ”๋ชจ๋ฆฌ ๋ˆ„์ˆ˜๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ๋“ฑ์˜ ๋ฌธ์ œ ๋ฐœ๊ฒฌ ์‹œ, ํ•ด๋‹น ๋ฌธ์ œ๋ฅผ ํ•ด๊ฒฐํ•˜๊ธฐ๊ฐ€ ์–ด๋ ต๋‹ค.

Managed Language

Java, Ruby, PHP ๋“ฑ ์ธํ„ฐํ”„๋ฆฌํ„ฐ, ์ปดํŒŒ์ผ๋Ÿฌ ํ˜น์€ ๋Ÿฐํƒ€์ž„ ํ™˜๊ฒฝ์—์„œ ๋™์ž‘ํ•˜๋Š” ์–ธ์–ด๋“ค์ด ํ•ด๋‹น ์˜์—ญ์— ์†ํ•œ๋‹ค. ํ•ด๋‹น ์–ธ์–ด๋“ค์€ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ง์ ‘ ๋ฉ”๋ชจ๋ฆฌ์— ์ ‘๊ทผํ•  ๊ถŒํ•œ์ด ์—†๊ฑฐ๋‚˜ ๊ทนํžˆ ์ œํ•œ์ ์ด๋‹ค. ๋–„๋ฌธ์— GC ๋“ฑ์„ ํ†ตํ•ด ์ž์ฒด์ ์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ด€๋ฆฌํ•œ๋‹ค. ๋‹ค๋งŒ Managed Language์— ๋น„ํ•ด ๋ฉ”๋ชจ๋ฆฌ ์ตœ์ ํ™” ์†๋„๊ฐ€ ๋Š๋ฆฌ๊ณ  ์‚ฌ์šฉ๋˜๋Š” ๋ฐฉ์‹์— ๋”ฐ๋ผ ๋‹ค์–‘ํ•œ ๋‹จ์ ์ด ์กด์žฌํ•œ๋‹ค.


Garbage Collector

์ง€๋‚œ ์‹œ๊ฐ„์„ ํ†ตํ•ด Reference Type์€ Heap ๋ฉ”๋ชจ๋ฆฌ์— ๊ฐ’์ด ์ €์žฅ๋œ๋‹ค๋Š” ๊ฒƒ์„ ๋ฐฐ์› ๋‹ค. ๊ธฐ์กด Java์—์„œ๋Š” GC ์ž‘์—…์ด ๊ฐœ๋ฐœ์ž๊ฐ€ ๊ด€์—ฌํ•˜์ง€ ์•Š๋„๋ก ๊ฐœ๋ฐœ๋˜์—ˆ๋Š”๋ฐ, JDK 1.2๋ถ€ํ„ฐ ์กฐ๊ธˆ์ด๋‚˜๋งˆ ๊ด€์—ฌ ํ•  ์ˆ˜ ์žˆ๋„๋ก ์ˆ˜์ •๋˜์—ˆ๋‹ค. ์ด๋ฅผ ํ†ตํ•ด java.lang.ref ํŒจํ‚ค์ง€๊ฐ€ ์ œ๊ณต๋˜์–ด Strong, Week, Soft, Phantom Reference ํด๋ž˜์Šค๋ฅผ ์ด์šฉํ•˜์—ฌ ๊ฐœ๋ฐœ์ž๊ฐ€ ๋ฉ”๋ชจ๋ฆฌ ์ตœ์ ํ™”์— ์ผ์ • ๋ถ€๋ถ„ ๊ด€์—ฌ ํ•  ์ˆ˜ ์žˆ๊ฒŒ ๋˜์—ˆ๋‹ค.

์ด๋Ÿฌํ•œ GC๋Š” ๋‘ ๊ฐ€์ง€ ๊ฐ€์ ˆ์„ ๊ธฐ์ค€์œผ๋กœ ๋งŒ๋“ค์–ด์กŒ๋‹ค.

  • ๋Œ€๋ถ€๋ถ„์˜ ๊ฐ์ฒด๋Š” ๊ธˆ๋ฐฉ ์ ‘๊ทผ ๋ถˆ๊ฐ€๋Šฅํ•œ ์ƒํƒœ(Un-Reachable)๊ฐ€ ๋œ๋‹ค.
  • ์˜ค๋ž˜๋œ ๊ฐ์ฒด์—์„œ ์ƒˆ๋กœ์šด ๊ฐ์ฒด๋กœ์˜ ์ฐธ์กฐ๋Š” ์•„์ฃผ ๋“œ๋ฌผ๊ฒŒ ์ผ์–ด๋‚œ๋‹ค.

๊ทธ๋ ‡๋‹ค๋ฉด GC๋Š” Heap ๋ฉ”๋ชจ๋ฆฌ์—์„œ ์ฐธ์กฐํ•˜์ง€ ์•Š๋Š” ๊ฐ’์„ ์ฐพ์•„ ์ œ๊ฑฐํ•˜๋Š”๋ฐ ์–ด๋–ป๊ฒŒ ์ง€์›Œ์•ผ ํ•  ๊ฐ’์ธ์ง€ ์•„๋‹Œ์ง€ ๊ตฌ๋ถ„ํ•˜๋Š”๊ฑธ๊นŒ? ๋งŒ์•ฝ GC๊ฐ€ ์ด๋ฅผ ๊ตฌ๋ถ„ํ•œ๋‹ค๋ฉด Heap ๋ฉ”๋ชจ๋ฆฌ๋Š” GC๊ฐ€ ๊ฐ’์„ ์ž˜ ๊ตฌ๋ถ„ ํ•  ์ˆ˜ ์žˆ๋„๋ก ์„ธ๋ถ€์ ์œผ๋กœ ์˜์—ญ์ด ๋‚˜๋‰˜์–ด์ ธ ์žˆ์ง€ ์•Š์„๊นŒ?

Reachablilty

๊ธฐ๋ณธ์ ์œผ๋กœ Heap ๋ฉ”๋ชจ๋ฆฌ์— ํ• ๋‹น๋œ ๊ฐ์ฒด๋Š” Reachablilty ๊ฐœ๋…์„ ํ†ตํ•ด ํ•ด๋‹น ๊ฐ์ฒด๊ฐ€ ์ฐธ์กฐ๋˜์—ˆ๋Š”์ง€ ๋˜์ง€ ์•Š์•˜๋Š”์ง€ ๊ตฌ๋ถ„๋œ๋‹ค.

โœ”๏ธ  Reachable ์œ ํšจํ•œ ์ฐธ์กฐ๊ฐ€ ์žˆ๋Š” ๊ฐ์ฒด

โœ”๏ธ  Un-Reachable ์–ด๋–ค ๊ณณ์—์„œ๋„ ์ฐธ์กฐํ•˜์ง€ ์•Š๋Š” ๊ฐ์ฒด, Garbage Collector ๋Œ€์ƒ

โœ”๏ธ  Root Set ๊ฐ์ฒด๊ฐ€ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋Š” ์ตœ์ดˆ์˜ ๊ฐ์ฒด๋ฅผ ์˜๋ฏธํ•œ๋‹ค. Root Set์„ ์ฐธ์กฐํ•˜๊ณ  ์žˆ๋Š” ๊ฐ์ฒด๋“ค์˜ ์ฐธ์กฐ๊ฐ€ ์กด์žฌํ•˜์ง€ ์•Š๋Š”๋‹ค๋ฉด ํ•ด๋‹น ๊ฐ์ฒด๋“ค๊ณผ Root Set ๊ฐ์ฒด๋Š” Un-Reachable ๋กœ ๊ฐ„์ฃผ๋˜์–ด GC์— ์˜ํ•ด ์ •๋ฆฌ๋œ๋‹ค. (21/05/17 hpotter1993๋‹˜, ํ”ผ๋“œ๋ฐฑ ๊ฐ์‚ฌํ•ฉ๋‹ˆ๋‹ค!)

Garbage Collector ๊ณผ์ •

(์ขŒ์ธก์€ JDK 1.7 ์ด์ „, ์šฐ์ธค์€ JDK 8 ์ดํ›„ / Perm ์˜์—ญ์ด MetaSpace๋กœ ๋ณ€๊ฒฝ๋˜์–ด OS์—์„œ ์ž์ฒด์ ์œผ๋กœ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ํ• ๋‹นํ•œ๋‹ค.)

1๏ธโƒฃ  Minor Garbage Collector Young Generetion ์—์„œ ๋ฐœ์ƒํ•œ๋‹ค.

2๏ธโƒฃ  Major Garbage Collector Old Generetion, Perm ์—์„œ ๋ฐœ์ƒํ•œ๋‹ค.

3๏ธโƒฃ  Full Garbage Collector ๋ชจ๋“  ์˜์—ญ์„ ๋Œ€์ƒ์œผ๋กœ ๋ฐœ์ƒํ•œ๋‹ค. ํ•ด๋‹น ์ข…๋ฅ˜์˜ GC๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉด JVM์ด ๋ฉˆ์ถ”๋Š”๋ฐ ์ด๋ฅผ Stop-the-World ๋ผ๊ณ  ํ•œ๋‹ค.

System.gc()

Runs the garbage collector. Calling the gc method suggests that the Java Virtual Machine expend effort toward recycling unused objects in order to make the memory they currently occupy available for quick reuse. When control returns from the method call, the Java Virtual Machine has made a best effort to reclaim space from all discarded objects.

System.gc() ๋ฉ”์†Œ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰ ์ค‘ ๊ฐ•์ œ์ ์œผ๋กœ GC๋ฅผ ์ˆ˜ํ–‰ํ•˜๊ฒŒ ๋œ๋‹ค. ํ•˜์ง€๋งŒ ๋ชจ๋“  ์Šค๋ ˆ๋“œ๊ฐ€ ๋ฉˆ์ถ”๊ธฐ ๋•Œ๋ฌธ์— ์ฝ”๋“œ ์ค‘๊ฐ„์— ํ•ด๋‹น ๋ฉ”์†Œ๋“œ๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ํ–‰์œ„๋Š” ํ•˜์ง€ ์•Š๋Š” ๊ฒƒ์ด ์ข‹๋‹ค.

public class GcTest {
    public static void main(String[] args) {
        long start = System.nanoTime();
        System.gc();
        long end = System.nanoTime();

        System.out.println(start - end + "ns");
    }
}

Young Generation

์ƒˆ๋กญ๊ฒŒ ์ƒ์„ฑ๋œ ๊ฐ์ฒด๊ฐ€ ์ฒ˜์Œ ๋จธ๋ฌด๋ฅด๋Š” ์˜์—ญ์ด๋‹ค. Minor GC๊ฐ€ ๊ด€์—ฌํ•˜๋Š” ์˜์—ญ์ด๋ฉฐ, HotSpot JVM์—์„œ๋Š” ๋น ๋ฅธ ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น์„ ์œ„ํ•ด ๋‘ ๊ฐ€์ง€ ๊ธฐ์ˆ ์„ ์‚ฌ์šฉํ•œ๋‹ค. bump-the-pointer ์™€ TLABs ๊ธฐ์ˆ ์ด๋‹ค.

๐Ÿ”Ž Eden new ์ƒ์„ฑ์ž๋กœ ์ƒˆ๋กญ๊ฒŒ ์ดˆ๊ธฐํ™”๋˜๊ฑฐ๋‚˜ ์ƒ์„ฑ๋œ ๊ฐ์ฒด๋“ค์ด ๊ฐ€์žฅ ์ฒ˜์Œ ๋จธ๋ฌด๋ฅด๋Š” ์˜์—ญ์ด๋‹ค. ํ•ด๋‹น ์˜์—ญ์ด ๋ชจ๋‘ ์ฐจ๋ฉด GC๊ฐ€ Un-Reachable ํ•œ ๊ฐ์ฒด๋ฅผ ์ฐพ์•„ ์ œ๊ฑฐํ•˜๊ณ  ์‚ด์•„๋‚จ์€ Reachable ๊ฐ์ฒด๋ฅผ Survivor 1 ์˜์—ญ์œผ๋กœ ์ด๋™์‹œํ‚จ๋‹ค.

๐Ÿ”Ž Survivor 1/2 Eden ์˜์—ญ์—์„œ ์‚ด์•„๋‚จ์€ Reachable ๊ฐ์ฒด๋“ค์ด Survivor 1 ์˜์—ญ์— ํ• ๋‹น๋˜๊ณ , ํ•ด๋‹น ์˜์—ญ์ด ๊ฝ‰ ์ฐจ๋ฉด ๋‹ค์‹œ GC๊ฐ€ Un-Reachable ํ•œ ๊ฐ์ฒด๋ฅผ ์ฐพ์•„ ์ œ๊ฑฐํ•œ ํ›„, Reachable ๊ฐ์ฒด๋ฅผ Survivor 2 ์˜์—ญ์œผ๋กœ ์ด๋™์‹œํ‚ค๊ณ  Survivor 1 ์˜์—ญ์„ ๋น„์šด๋‹ค. Survivor 2 ์˜์—ญ์ด ์ฐจ๊ฒŒ ๋˜๋ฉด ๋‹ค์‹œ ์œ„์˜ ๊ณผ์ •์„ ๊ฑฐ์ณ Survivor 1์— ๊ฐ์ฒด๋ฅผ ์˜ฎ๊ธฐ๊ณ  Survivor 2 ์˜์—ญ์„ ๋น„์šด๋‹ค. ์ฆ‰, ๋‘ ์˜์—ญ ์ค‘ ํ•œ ์˜์—ญ์€ ๋น„์›Œ์ ธ ์žˆ์–ด์•ผ ํ•œ๋‹ค. ์˜ˆ์™ธ์ ์œผ๋กœ ํ•ด๋‹น ์˜์—ญ์„ ๊ฑฐ์น˜์ง€ ์•Š๊ณ  Old ์˜์—ญ์œผ๋กœ ๋‹ค์ด๋ ‰ํŠธ๋กœ ๋„˜์–ด๊ฐ€๋Š” ๊ฒฝ์šฐ๊ฐ€ ์žˆ๋Š”๋ฐ, ์ด๋Š” ๊ฐ์ฒด์˜ ํฌ๊ธฐ๊ฐ€ Survivor ํฌ๊ธฐ๋ณด๋‹ค ํด ๊ฒฝ์šฐ์— ํ•ด๋‹น๋œ๋‹ค.

Old Generetion

Young ์˜์—ญ์—์„œ ์‚ด์•„๋‚จ์€ Reachable ๊ฐ์ฒด๋กœ Full GC, Major GC ๊ฐ€ ์ผ์–ด๋‚˜์ง€ ์•Š๋Š” ์ด์ƒ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ์‚ฌ๋ผ์ง€์ง€ ์•Š๋Š”๋‹ค. ์ด ๋•Œ, ์ฒ˜๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์€ JDK 7์„ ๊ธฐ์ค€์œผ๋กœ 5๊ฐ€์ง€๊ฐ€ ์กด์žฌํ•œ๋‹ค.


GC์˜ ์ข…๋ฅ˜

๐Ÿ’ฅ Serial GC (-XX:+UseSerialGC)

Young ๊ณผ Old ์˜์—ญ์ด ์—ฐ์†์ ์œผ๋กœ ์ฒ˜๋ฆฌ๋˜๋ฉฐ ํ•ด๋‹น GC๊ฐ€ ์ˆ˜ํ–‰๋  ๋•Œ JVM์˜ ์ˆ˜ํ–‰์„ ๋ฉˆ์ถ”๊ณ  GC๋ฅผ ์ˆ˜ํ–‰ํ•˜๋Š”๋ฐ, ์ด๋ฅผ Sun์—์„œ๋Š” Stop-the World๋ผ๊ณ  ํ‘œํ˜„ํ•œ๋‹ค. ๋ฉ€ํ‹ฐ ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ๋Š” ์‚ฌ์šฉ ํ•  ์ˆ˜ ์—†๋Š” ์‹ฑ๊ธ€ ์Šค๋ ˆ๋“œ ์‹œ์Šคํ…œ์— ์ ํ•ฉํ•œ GC๋กœ, ๋ชจ๋“  ์ข…๋ฅ˜์˜ GC๋ฅผ ์ˆ˜ํ–‰ํ•œ๋‹ค. Young ์˜์—ญ์—์„œ๋Š” Serial ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ์‚ฌ์šฉ๋˜๊ณ , Old ์˜์—ญ์—์„œ๋Š” Serial Mark-Sweep-Compact ์•Œ๊ณ ๋ฆฌ์ฆ˜์ด ์‚ฌ์šฉ๋œ๋‹ค.

โžก๏ธ Mark-Sweep-Compact ์•Œ๊ณ ๋ฆฌ์ฆ˜ Old ์˜์—ญ์— ์‚ด์•„์žˆ๋Š” ๊ฐ์ฒด๋ฅผ ์‹๋ณ„(Mark)ํ•˜๊ณ  Heap ๋ฉ”๋ชจ๋ฆฌ์˜ ์•ž๋ถ€๋ถ„๋ถ€ํ„ฐ ํ™•์ธํ•ด์„œ Reachableํ•œ ๊ฐ์ฒด๋งŒ ๋‚จ๊ธด๋‹ค.(Sweep) ๋งˆ์ง€๋ง‰์œผ๋กœ Reachable ๊ฐ์ฒด๋“ค์ด ์—ฐ์†์œผ๋กœ Heap ๋ฉ”๋ชจ๋ฆฌ์˜ ๊ฐ€์žฅ ์•ž์—์„œ ๋ถ€ํ„ฐ ์Œ“์ด๋„๋ก ํ•œ ๋‹ค์Œ ๊ฐ์ฒด๊ฐ€ ์กด์žฌํ•˜๋Š” ๊ณต๊ฐ„๊ณผ ์กด์žฌํ•˜์ง€ ์•Š๋Š” ๊ณต๊ฐ„์„ ๋‚˜๋ˆ„์–ด ์ˆ˜ํ–‰ํ•œ๋‹ค.(Compact)

๐Ÿ’ฅ Parallel GC (-XX:+UseParallelGC)

Parallel GC๋Š” ๊ธฐ๋ณธ์ ์œผ๋กœ Old ์˜์—ญ์—์„œ๋Š” Serial GC์™€ ๋™์ผํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ ๋™์ž‘ํ•˜์ง€๋งŒ Young ์˜์—ญ์—์„œ๋Š” ๋ณ‘๋ ฌ๋กœ ์ฒ˜๋ฆฌํ•ด CPU๋ฅผ ์‚ฌ์šฉํ•ด GC์˜ ๋ถ€ํ•˜๋ฅผ ์ค„์—ฌ CPU์˜ ๋Œ€๊ธฐ ์ƒํƒœ๋ฅผ ์ตœ์†Œํ™”ํ•˜์—ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„ฑ์„์„ ๋Œ์–ด ์˜ฌ๋ฆด ์ˆ˜ ์žˆ๋‹ค. ๋ณดํ†ต ThroughPut GC ๋ผ๊ณ ๋„ ๋ถ€๋ฅธ๋‹ค.

๐Ÿ’ฅ Parallel Old GC

Young ์˜์—ญ์—์„œ๋Š” ๋ณ‘๋ ฌ์ ์œผ๋กœ Garbage๋ฅผ ์ฒ˜๋ฆฌํ•˜๋ฉฐ, Old ์˜์—ญ์—์„œ๋Š” Mark-Summary-Compaction ๋‹จ๊ณ„๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์ฒ˜๋ฆฌํ•œ๋‹ค. Parallel GC์˜ Mark-Sweep-Compact ์•Œ๊ณ ๋ฆฌ์ฆ˜์—์„œ Sweep ๋ถ€๋ถ„๊ณผ Summary ๋ถ€๋ถ„์ด ์•ฝ๊ฐ„ ๋‹ค๋ฅธ๋ฐ, Summary ๋‹จ๊ณ„์—์„œ GC๋ฅผ ์ˆ˜ํ–‰ํ•œ ์˜์—ญ์—์„œ ํ•œ๋ฒˆ ๋” Reachable ๊ฐ์ฒด๋ฅผ ํ•œ์ธํ•œ๋‹ค๋Š” ์ ์—์„œ ์กฐ๊ธˆ ๋” ๋ณต์žกํ•˜๋‹ค.

๐Ÿ’ฅ CMS GC (-XX:+UseConcMarkSweepGC)

๊ธฐ์กด์˜ ๋‹ค๋ฅธ GC ๋ฐฉ์‹๋ณด๋‹ค ํ›จ์”ฌ ๋ณต์žกํ•œ๋ฐ, ์ด 3๋”˜๊ณ„์˜ Mark ๋‹จ๊ณ„๋ฅผ ๊ฑฐ์นœ๋‹ค. 1) Init Mark ๋‹จ๊ณ„์—์„œ๋Š” ํด๋ž˜์Šค ๋กœ๋”์—์„œ ๊ฐ€๊นŒ์šด Reachable ๊ฐ์ฒด๋ฅผ ํ™•์ธํ•˜๊ณ , 2)ํ•ด๋‹น ๊ฐ์ฒด๋“ค์„ Current Mark ๋‹จ๊ณ„์—์„œ Root Set ๊ฐ์ฒด๋ฅผ ๋”ฐ๋ผ ํ™•์ธํ•œ๋‹ค. ์ด ๋‹จ๊ณ„์—์„œ๋Š” ๋‹ค๋ฅธ ์Šค๋ ˆ๋“œ๊ฐ€ ์‹คํ–‰ ์ค‘ ์ผ ๋•Œ ๋™์‹œ์— ์ง„ํ–‰๋œ๋‹ค. 3) Remark ๋‹จ๊ณ„์—์„œ๋Š” ์ด์ „ ๋‹จ๊ณ„์—์„œ ์ƒˆ๋กœ ์ƒ์„ฑ๋˜๊ฑฐ๋‚˜ ์ฐธ์กฐ๊ฐ€ ๋Š๊ธด ๊ฐ์ฒด๋ฅผ ํ™•์ธํ•˜๊ณ , ์ด๋ฅผ Cuncurrent Sweep ๋‹จ๊ณ„๋กœ ๋„˜๊ฒจ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ตœ์ ํ™”ํ•œ๋‹ค. ์ด๋Ÿฌํ•œ ๋‹จ๊ณ„๋กœ ์ง„ํ–‰๋˜๊ธฐ ๋•Œ๋ฌธ์— Stop-the-World ์‹œ๊ฐ„์ด ์งง์•„์ ธ ์‹คํ–‰ ์ค‘์ธ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์˜ ์‘๋‹ต ์†๋„๊ฐ€ ์ค‘์š”ํ•  ๋•Œ ์‚ฌ์šฉ๋œ๋‹ค. ๊ทธ๋ž˜์„œ CMS GC๋ฅผ Low Latency GC๋ผ๊ณ  ๋ถ€๋ฅธ๋‹ค. ํ•˜์ง€๋งŒ ์ด๋Ÿฐ ์ด์ ์—๋„ ๋ถˆ๊ตฌํ•˜๊ณ  CMS GC๋Š” Compaction ๊ณผ์ •์ด ์กด์žฌํ•˜์ง€ ์•Š๊ธฐ ๋•Œ๋ฌธ์— ๋ฉ”๋ชจ๋ฆฌ ๋‹จํŽธํ™”๋ผ๋Š” ๋ฌธ์ œ๊ฐ€ ๋ฐœ์ƒํ•˜๋ฉฐ, ๋‹ค๋ฅธ GC ๋ฐฉ์‹๋ณด๋‹ค ๋” ๋งŽ์€ ๋ฉ”๋ชจ๋ฆฌ์™€ CPU๋ฅผ ์‚ฌ์šฉํ•œ๋‹ค.

๐Ÿ’ฅ G1 (Garbage First) GC

ํฐ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ๊ฐ€์ง„ ๋ฉ€ํ‹ฐ ํ”„๋กœ์„ธ์„œ ์‹œ์Šคํ…œ์— ์‚ฌ์šฉํ•˜๊ธฐ ์œ„ํ•œ ๋ชฉ์ ์œผ๋กœ ๊ฐœ๋ฐœ๋œ GC๋กœ, ๋ณ‘๋ ฌ ์Šค๋ ˆ๋“œ ๋ฐ ๋™์‹œ ์Šค๋ ˆ๋“œ ๋ชจ๋‘ ์‚ฌ์šฉํ•˜๋ฉฐ, Java ํ”„๋กœ๊ทธ๋žจ์ด ์‹คํ–‰๋˜๋Š” ๋™์•ˆ ๋™์‹œ ์Šค๋ ˆ๋“œ๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ ์‚ด์•„์žˆ๋Š” Reachable ๊ฐ์ฒด๋ฅผ ํƒ์ƒ‰ํ•˜๊ณ , ๋ณ‘๋ ฌ ์Šค๋ ˆ๋“œ๋ฅผ ์ด์šฉํ•ด ํ•ด๋‹น ๊ฐ์ฒด๋ฅผ ๋น ๋ฅด๊ฒŒ ๋ณต์‚ฌํ•ด์„œ Stop-the-World ์‹œ๊ฐ„์„ ๋‹จ์ถ•ํ•˜๋ฉด์„œ ๋ณ„๋„์˜ ์„ค์ •์„ ํ•˜์ง€ ์•Š์•„๋„ ๊ฐ€๋Šฅํ•œ ํ•œ ์ฒ˜๋ฆฌ๋Ÿ‰์„ ํ™•๋ณดํ•˜๋Š” ๊ฒƒ์„ ๋ชฉํ‘œ๋กœ ํ•œ๋‹ค. JDK 7 ๋ถ€ํ„ฐ ์ •์‹ ์ง€์›ํ•˜๋ฉฐ JDK 9 ๋ถ€ํ„ฐ Default GC๋กœ ์‚ฌ์šฉ๋œ๋‹ค. ๋‹ค๋งŒ, Stop-the-World์˜ ์‹œ๊ฐ„์ด ๋‹จ์ถ•๋˜์—ˆ๋‹ค๊ณ  ํ•ด์„œ G1 GC๊ฐ€ ์‹ค์‹œ๊ฐ„(Real Time) GC๋Š” ์•„๋‹ˆ๋‹ค.

G1 GC๋Š” CMS GC์™€ ๋น„์Šทํ•˜๊ฒŒ ์ž‘๋™๋˜์ง€๋งŒ, G1 GC๋Š” ์ „์—ญ ํ‘œ์‹œ ๋‹จ๊ณ„๋ฅผ ๊ฑฐ์ฒ˜ Heap ์ „์ฒด์— ๊ฐ์ฒด ์ˆ˜๋ช…์„ ๊ฒฐ์ •ํ•œ๋‹ค. ์ด ๋•Œ, ํ‘œ์‹œ ๋‹จ๊ณ„๊ฐ€ ์™„๋ฃŒ๋˜๋ฉด G1 GC๋Š” ์–ด๋–ค ์˜์—ญ์ด ๋น„์›Œ์ ธ์•ผ ํ•˜๋Š”์ง€ ์•Œ๊ฒŒ ๋˜๊ณ , ์ด๋ฅผ ์ค‘์ ์ ์œผ๋กœ ๋น ๋ฅด๊ฒŒ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ •๋ฆฌํ•œ๋‹ค.


๐Ÿคฆ‍โ™‚๏ธ Garbage Collector๋ฅผ ์ •๋ฆฌํ•˜๋Š”๋ฐ ์ •๋ง ์˜ค๋ž˜ ์‹œ๊ฐ„์ด ๊ฑธ๋ฆฐ ๊ฒƒ ๊ฐ™๋‹ค.
๋ฌด์—‡๋ณด๋‹ค ์—ฌ๋Ÿฌ ๋ธ”๋กœ๊ทธ๋ฅผ ๊ฒ€์ƒ‰ํ•ด์„œ ์ฝ์–ด๋ด๋„ ์ดํ•ด๋˜์ง€ ์•Š๋Š” ๋ถ€๋ถ„์ด ๋„ˆ๋ฌด ๋งŽ์•„์„œ ๊ณ„์† ๋ฐ˜๋ณตํ•ด์„œ ๋‹ค์‹œ ์ƒ๊ฐํ•˜๋Š” ๋ฐฉ์‹์œผ๋กœ ๊ณต๋ถ€ํ•˜๋‹ค ๋ณด๋‹ˆ ๊ทธ๋Ÿฐ ๊ฒƒ ๊ฐ™๋‹ค.

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

๊ทธ๋ž˜๋„ ๋‚ด๊ฐ€ ๋˜ ํ•˜๋‚˜ ๋” ์•Œ๊ฒŒ ๋˜์—ˆใ„ท๋Š” ์ ์—์„œ ๋ฟŒ๋“ฏํ•˜๊ณ  ์žฌ๋ฐŒ๋‹ค!
์ด๋ฒˆ ๋‚ด์šฉ์€ Java ํ”„๋กœ๊ทธ๋ž˜๋ฐ์˜ ๊ทผ๊ฐ„์ด ๋˜๋Š” ๋‚ด์šฉ์ด๋‹ˆ๊นŒ ๊พธ์ค€ํžˆ ์ƒ๊ธฐํ•  ์ˆ˜ ์žˆ๋„๋ก ํ•ด์•ผ๊ฒ ๋‹ค.
(๊ทธ๋ฆฌ๊ณ  ์˜์–ด ์›๋ฌธ๋„ ์ฝ๊ณ  ์ดํ•ด ํ•  ์ˆ˜ ์žˆ๋„๋ก ๋…ธ๋ ฅํ•ด์•ผ๊ฒ ๋‹ค!)

์ฐธ๊ณ  ๋ฌธ์„œ

Understanding Garbage Collectors

Getting Started with the G1 Garbage Collector

NAVER D2

 

Tunning

Configuring Axional Server for highload, albeit for load testing or for production, requires that the operating system, the JVM, the network and the load generation all be tuned. The following document shows the major parameters to configure on a server ma

docs.deistercloud.com

 

JVM ๋ฉ”๋ชจ๋ฆฌ ๊ตฌ์กฐ์™€ GC

์ž‘์„ฑ์ค‘์ธ ๋ฌธ์„œ

johngrib.github.io

 

'Programming > Java' ์นดํ…Œ๊ณ ๋ฆฌ์˜ ๋‹ค๋ฅธ ๊ธ€

F010 - System.out.println(), Logger  (0) 2021.05.19
F009 - Inheritance, Composition  (0) 2021.05.18
F007 - JVM : Memory Architecture  (0) 2021.05.14
F006 - Throwable, Exception, Error  (0) 2021.05.11
F005 - Stack & Heap Memory  (0) 2021.05.08