๐Ÿ›‘ JVM์˜ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜์ด๋ž€?

์„ํ˜„ยท2025๋…„ 2์›” 8์ผ

Insight

๋ชฉ๋ก ๋ณด๊ธฐ
2/43

๐Ÿง ์˜ค๋Š˜์˜ ์ด์•ผ๊ธฐ

ํšŒ์‚ฌ์— ๋™๋ฃŒ ์‹ ์ž… ๊ฐœ๋ฐœ์ž ๋ถ„๋“ค์„ ์œ„ํ•ด ์ •๋ฆฌํ•˜๋‹ค๊ฐ€ ๋ธ”๋กœ๊ทธ์—๋„ ์ •๋ฆฌํ•ด๋ณด๋ฉด ์ข‹์„ ๊ฒƒ ๊ฐ™์•„ ์ž‘์„ฑํ•˜๊ฒŒ ๋˜์—ˆ์Šต๋‹ˆ๋‹ค. JVM(Java Virtual Machine)์—์„œ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜(GC)์€ ๋ฉ”๋ชจ๋ฆฌ๋ฅผ ์ž๋™์œผ๋กœ ๊ด€๋ฆฌํ•ด ์ฃผ๋Š” ์ค‘์š”ํ•œ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ, GC๊ฐ€ ์–ธ์ œ ๊ฐ์ฒด๋ฅผ ์ œ๊ฑฐํ•˜๋Š”์ง€, ์–ด๋–ค ๋ฐฉ์‹์œผ๋กœ ๋™์ž‘ํ•˜๋Š”์ง€ ์ •ํ™•ํžˆ ์ดํ•ดํ•˜๋Š” ๊ฒƒ์€ ์‰ฝ์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ํŠนํžˆ, Stop-the-World(STW) ํ˜„์ƒ์€ ์„ฑ๋Šฅ์— ํฐ ์˜ํ–ฅ์„ ๋ฏธ์น  ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ์— ์ด์— ๋Œ€ํ•œ ์ดํ•ด๊ฐ€ ํ•„์š”ํ•ฉ๋‹ˆ๋‹ค.

์ด๋ฒˆ ๊ธ€์—์„œ๋Š” GC๊ฐ€ ๋„๋‹ฌ ๊ฐ€๋Šฅ์„ฑ์„ ํŒ๋‹จํ•˜๋Š” ๋ฐฉ์‹๊ณผ ๊ฐœ๋ฐœ์ž๊ฐ€ ์ด๋ฅผ ์–ด๋–ป๊ฒŒ ํ™œ์šฉํ•  ์ˆ˜ ์žˆ๋Š”์ง€๋ฅผ ์„ค๋ช…ํ•˜๊ณ , Stop-the-World๋ž€ ๋ฌด์—‡์ด๋ฉฐ, ์ด๋ฅผ ์ตœ์†Œํ™”ํ•˜๋Š” ๋ฐฉ๋ฒ•๊นŒ์ง€ ์‚ดํŽด๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๐Ÿš€


1๏ธโƒฃ GC๋Š” ๊ฐ์ฒด์˜ ๋„๋‹ฌ ๊ฐ€๋Šฅ์„ฑ(Reachability)์„ ์–ด๋–ป๊ฒŒ ํŒ๋‹จํ• ๊นŒ? ๐Ÿค”

JVM์—์„œ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜์€ ๋„๋‹ฌ ๊ฐ€๋Šฅ์„ฑ(Reachability)์„ ๊ธฐ์ค€์œผ๋กœ ๊ฐ์ฒด๋ฅผ ์ •๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์ฆ‰, ์–ด๋–ค ๊ฐ์ฒด๊ฐ€ ๋” ์ด์ƒ ์‚ฌ์šฉ๋˜์ง€ ์•Š๋Š”๋‹ค๋ฉด, ํ•ด๋‹น ๊ฐ์ฒด๋Š” GC์˜ ๋Œ€์ƒ์ด ๋ฉ๋‹ˆ๋‹ค.

โœ… ๋„๋‹ฌ ๊ฐ€๋Šฅ์„ฑ ํŒ๋‹จ ๊ธฐ์ค€

  1. ๋ฃจํŠธ ์ง‘ํ•ฉ(Root Set): JVM์€ ํŠน์ • ๊ฐ์ฒด๋ฅผ ๋ฃจํŠธ๋กœ ์‚ผ๊ณ , ์ด๋ฅผ ๊ธฐ์ค€์œผ๋กœ ๋„๋‹ฌ ๊ฐ€๋Šฅํ•œ ๊ฐ์ฒด๋ฅผ ํƒ์ƒ‰ํ•ฉ๋‹ˆ๋‹ค. ๋ฃจํŠธ ์ง‘ํ•ฉ์—๋Š” ๋‹ค์Œ์ด ํฌํ•จ๋ฉ๋‹ˆ๋‹ค:

    • ์Šคํƒ(Stack) ์˜์—ญ์˜ ์ง€์—ญ ๋ณ€์ˆ˜ (๋ฉ”์„œ๋“œ ๋‚ด๋ถ€ ๋ณ€์ˆ˜ ๋“ฑ)
    • ๋ฉ”์„œ๋“œ(Method) ์˜์—ญ์˜ ์ •์  ๋ณ€์ˆ˜ (static ๋ณ€์ˆ˜)
    • JNI(Java Native Interface)๋กœ ์ƒ์„ฑ๋œ ๊ฐ์ฒด (๋„ค์ดํ‹ฐ๋ธŒ ์ฝ”๋“œ์—์„œ ์ฐธ์กฐํ•˜๋Š” ๊ฐ์ฒด)
  2. ๊ฐ์ฒด ์ฐธ์กฐ ๊ทธ๋ž˜ํ”„ ํƒ์ƒ‰: ๋ฃจํŠธ ์ง‘ํ•ฉ์—์„œ๋ถ€ํ„ฐ ์‹œ์ž‘ํ•˜์—ฌ, ์ฐธ์กฐ๋œ ๊ฐ์ฒด๋“ค์„ ์ˆœ์ฐจ์ ์œผ๋กœ ํƒ์ƒ‰ํ•˜๋ฉฐ ๋„๋‹ฌ ๊ฐ€๋Šฅํ•œ ๊ฐ์ฒด๋ฅผ ์‹๋ณ„ํ•ฉ๋‹ˆ๋‹ค.

  3. ๋„๋‹ฌ ๋ถˆ๊ฐ€๋Šฅ ๊ฐ์ฒด(Garbage) ์‹๋ณ„: ๋ฃจํŠธ ์ง‘ํ•ฉ์œผ๋กœ๋ถ€ํ„ฐ ์ฐธ์กฐ๋˜์ง€ ์•Š๋Š” ๊ฐ์ฒด๋Š” GC์˜ ๋Œ€์ƒ์ด ๋ฉ๋‹ˆ๋‹ค.

โœ… ์˜ˆ์ œ ์ฝ”๋“œ (GC ๋Œ€์ƒ ๊ฐ์ฒด ์‹๋ณ„)

import java.util.ArrayList;
import java.util.List;

public class GCDemo {
    static List<Object> globalList = new ArrayList<>();
    
    public static void main(String[] args) {
        Object obj1 = new Object(); // ์Šคํƒ ๋ณ€์ˆ˜ (GC ๋Œ€์ƒ X)
        globalList.add(obj1); // static ๋ณ€์ˆ˜์—์„œ ์ฐธ์กฐ (GC ๋Œ€์ƒ X)
        
        Object obj2 = new Object(); // ์ƒˆ๋กœ์šด ๊ฐ์ฒด ์ƒ์„ฑ
        obj2 = null; // GC ๋Œ€์ƒ์ด ๋จ

        System.gc(); // ๊ฐ•์ œ GC ์š”์ฒญ
        
        System.out.println("GC ์‹คํ–‰ ์™„๋ฃŒ!");
    }
}

obj1์€ globalList์—์„œ ์ฐธ์กฐ๋˜๊ธฐ ๋•Œ๋ฌธ์— GC ๋Œ€์ƒ์ด ์•„๋‹™๋‹ˆ๋‹ค. ๋ฐ˜๋ฉด, obj2๋Š” ์ฐธ์กฐ๊ฐ€ ์ œ๊ฑฐ๋˜์—ˆ๊ธฐ ๋•Œ๋ฌธ์— GC ๋Œ€์ƒ์ด ๋ฉ๋‹ˆ๋‹ค.


2๏ธโƒฃ ๊ฐœ๋ฐœ์ž๊ฐ€ GC์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ์„๊นŒ? ๐Ÿคจ

Java์—์„œ๋Š” java.lang.ref ํŒจํ‚ค์ง€๋ฅผ ํ™œ์šฉํ•˜์—ฌ GC๊ฐ€ ๊ฐ์ฒด๋ฅผ ์ •๋ฆฌํ•˜๋Š” ๋ฐฉ์‹์— ์˜ํ–ฅ์„ ์ค„ ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.

โœ… SoftReference์™€ WeakReference

  • SoftReference: ๋ฉ”๋ชจ๋ฆฌ๊ฐ€ ๋ถ€์กฑํ•  ๋•Œ๋งŒ GC๊ฐ€ ํ•ด๋‹น ๊ฐ์ฒด๋ฅผ ์ •๋ฆฌํ•จ.
  • WeakReference: ์ฐธ์กฐ๊ฐ€ ์•ฝํ•˜์—ฌ GC๊ฐ€ ์‹คํ–‰๋  ๋•Œ ์ฆ‰์‹œ ์ˆ˜๊ฑฐ๋  ์ˆ˜ ์žˆ์Œ.

โœ… ์˜ˆ์ œ ์ฝ”๋“œ (WeakReference ํ™œ์šฉ)

import java.lang.ref.WeakReference;

public class WeakReferenceExample {
    public static void main(String[] args) {
        Object strongRef = new Object();
        WeakReference<Object> weakRef = new WeakReference<>(strongRef);
        
        strongRef = null; // ๊ฐ•ํ•œ ์ฐธ์กฐ ์ œ๊ฑฐ
        System.gc(); // GC ์‹คํ–‰ ์š”์ฒญ
        
        if (weakRef.get() == null) {
            System.out.println("๊ฐ์ฒด๊ฐ€ GC์— ์˜ํ•ด ์ œ๊ฑฐ๋˜์—ˆ์Šต๋‹ˆ๋‹ค.");
        } else {
            System.out.println("๊ฐ์ฒด๋Š” ์•„์ง ์‚ด์•„ ์žˆ์Šต๋‹ˆ๋‹ค.");
        }
    }
}

WeakReference๋ฅผ ์‚ฌ์šฉํ•˜๋ฉด GC๊ฐ€ ์‹คํ–‰๋  ๋•Œ ๊ฐ์ฒด๊ฐ€ ๋” ๋นจ๋ฆฌ ์ •๋ฆฌ๋ฉ๋‹ˆ๋‹ค.


3๏ธโƒฃ Stop-the-World(STW)๋ž€? ๐Ÿ›‘

GC๊ฐ€ ์‹คํ–‰๋  ๋•Œ JVM์€ ์ผ์‹œ์ ์œผ๋กœ ๋ชจ๋“  ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์Šค๋ ˆ๋“œ๋ฅผ ๋ฉˆ์ถ”๊ณ (GC ์ˆ˜ํ–‰์„ ์œ„ํ•ด), ํ•„์š”ํ•œ ๊ฐ์ฒด๋ฅผ ์ •๋ฆฌํ•ฉ๋‹ˆ๋‹ค. ์ด ํ˜„์ƒ์„ Stop-the-World(STW)๋ผ๊ณ  ํ•ฉ๋‹ˆ๋‹ค.

โœ… STW๊ฐ€ ๋ฐœ์ƒํ•˜๋Š” ์›์ธ

  1. GC ์ˆ˜ํ–‰ ์ค‘ ๊ฐ์ฒด ์ฐธ์กฐ๋ฅผ ๋ณ€๊ฒฝํ•˜๋ฉด ๋ฐ์ดํ„ฐ ๋ฌด๊ฒฐ์„ฑ์ด ๊นจ์งˆ ์ˆ˜ ์žˆ๊ธฐ ๋•Œ๋ฌธ
  2. ๊ฐ์ฒด๋ฅผ ์•ˆ์ „ํ•˜๊ฒŒ ์ •๋ฆฌํ•˜๊ธฐ ์œ„ํ•ด ๋ชจ๋“  ์ž‘์—…์„ ์ค‘๋‹จํ•ด์•ผ ํ•˜๊ธฐ ๋•Œ๋ฌธ

โœ… STW ์ตœ์†Œํ™”ํ•˜๋Š” ๋ฐฉ๋ฒ•

  • G1 GC ์‚ฌ์šฉ: STW ์‹œ๊ฐ„์„ ์ตœ์†Œํ™”ํ•˜๋Š” ํ˜„๋Œ€์ ์ธ GC ๋ฐฉ์‹.
  • CMS(Concurrent Mark-Sweep) GC ์‚ฌ์šฉ: GC๋ฅผ ๋ณ‘๋ ฌ๋กœ ์ˆ˜ํ–‰ํ•˜์—ฌ ๋ฉˆ์ถ”๋Š” ์‹œ๊ฐ„์„ ์ค„์ž„.
  • ZGC ์‚ฌ์šฉ: ์ตœ์‹  JVM์—์„œ ์ œ๊ณตํ•˜๋Š” ์ดˆ์ €์ง€์—ฐ GC.

โœ… STW ์˜ˆ์ œ ์ฝ”๋“œ (STW ๋ฐœ์ƒ ํ™•์ธ)

public class StopTheWorldDemo {
    public static void main(String[] args) {
        Runnable task = () -> {
            while (true) {
                byte[] memory = new byte[10 * 1024 * 1024]; // 10MB ํ• ๋‹น
                try {
                    Thread.sleep(50); // ๋ฉ”๋ชจ๋ฆฌ ์ฆ๊ฐ€ ์†๋„ ์กฐ์ ˆ
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        };
        new Thread(task).start();
        
        while (true) {
            long start = System.currentTimeMillis();
            System.gc(); // ๊ฐ•์ œ GC ์‹คํ–‰
            long end = System.currentTimeMillis();
            System.out.println("GC ์‹คํ–‰ ์‹œ๊ฐ„: " + (end - start) + "ms");
        }
    }
}

์ด ์ฝ”๋“œ์—์„œ System.gc()๋ฅผ ์‹คํ–‰ํ•˜๋ฉด STW๊ฐ€ ๋ฐœ์ƒํ•˜์—ฌ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์ด ๋ฉˆ์ถ”๋Š” ์‹œ๊ฐ„์ด ์ฆ๊ฐ€ํ•  ์ˆ˜ ์žˆ์Šต๋‹ˆ๋‹ค.


๐Ÿ”ฅ ๋งˆ๋ฌด๋ฆฌ

JVM์˜ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜์€ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์„ฑ๋Šฅ๊ณผ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ๋ฅผ ์œ„ํ•ด ํ•„์ˆ˜์ ์ธ ๊ธฐ๋Šฅ์ž…๋‹ˆ๋‹ค. ํ•˜์ง€๋งŒ, Stop-the-World(STW) ํ˜„์ƒ์„ ์ตœ์†Œํ™”ํ•˜๊ณ , GC ์„ฑ๋Šฅ์„ ์ตœ์ ํ™”ํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ์ดํ•ดํ•˜๋Š” ๊ฒƒ์ด ์ค‘์š”ํ•ฉ๋‹ˆ๋‹ค.

๐Ÿ“Œ ์š”์•ฝ

โœ” GC๋Š” ๋„๋‹ฌ ๊ฐ€๋Šฅ์„ฑ(Reachability)์„ ๊ธฐ์ค€์œผ๋กœ ๊ฐ์ฒด๋ฅผ ์ •๋ฆฌํ•œ๋‹ค.
โœ” SoftReference์™€ WeakReference๋ฅผ ํ™œ์šฉํ•˜๋ฉด GC ์˜ํ–ฅ์„ ์กฐ์ ˆํ•  ์ˆ˜ ์žˆ๋‹ค.
โœ” Stop-the-World(STW)๋Š” GC ์ˆ˜ํ–‰ ์ค‘ JVM์ด ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์„ ๋ฉˆ์ถ”๋Š” ํ˜„์ƒ์ด๋‹ค.
โœ” ์ตœ์‹  JVM์—์„œ๋Š” G1 GC, CMS GC, ZGC๋ฅผ ์‚ฌ์šฉํ•˜์—ฌ STW๋ฅผ ์ค„์ผ ์ˆ˜ ์žˆ๋‹ค.

์ด์ œ JVM์˜ GC ๋™์ž‘ ๋ฐฉ์‹๊ณผ STW๋ฅผ ์ดํ•ดํ•˜๊ณ , ํšจ์œจ์ ์ธ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ๋ฅผ ์ ์šฉํ•ด ๋ณด์„ธ์š”! ๐Ÿš€


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