Skip to content

Latest commit

ย 

History

History
353 lines (291 loc) ยท 9.58 KB

jvm-gc.md

File metadata and controls

353 lines (291 loc) ยท 9.58 KB

JVM๊ณผ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜์— ๋Œ€ํ•œ ๊ธฐ์ˆ  ๋ฉด์ ‘ ๋‹ต๋ณ€

์ฃผ์š” ์งˆ๋ฌธ

"JVM์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ตฌ์กฐ์™€ ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜์˜ ๋™์ž‘ ๋ฐฉ์‹์— ๋Œ€ํ•ด ์„ค๋ช…ํ•ด์ฃผ์„ธ์š”. ๊ฐ GC ์•Œ๊ณ ๋ฆฌ์ฆ˜์˜ ์žฅ๋‹จ์ ์€ ๋ฌด์—‡์ธ๊ฐ€์š”?"

1. JVM ๋ฉ”๋ชจ๋ฆฌ ๊ตฌ์กฐ

1.1 Heap ์˜์—ญ

public class HeapStructure {
    // Young Generation
    // - Eden
    // - Survivor 0
    // - Survivor 1
    
    // Old Generation
    
    public static void main(String[] args) {
        // Eden ์˜์—ญ์— ๊ฐ์ฒด ์ƒ์„ฑ
        Object obj = new Object();
        
        // ํฐ ๊ฐ์ฒด๋Š” ๋ฐ”๋กœ Old Generation์œผ๋กœ
        byte[] bigArray = new byte[1024 * 1024 * 10]; // 10MB
    }
}

1.2 Non-Heap ์˜์—ญ

public class NonHeapStructure {
    // Method Area (Metaspace in Java 8+)
    static final String CONSTANT = "This is constant";
    
    // Stack
    public void stackExample() {
        int localVar = 42;  // Stack์— ์ €์žฅ
        Object obj = new Object();  // ์ฐธ์กฐ๋Š” Stack, ๊ฐ์ฒด๋Š” Heap
    }
}

2. ๊ฐ€๋น„์ง€ ์ปฌ๋ ‰์…˜ ์•Œ๊ณ ๋ฆฌ์ฆ˜

2.1 Serial GC

// Serial GC ์‚ฌ์šฉ ์„ค์ •
// -XX:+UseSerialGC
public class SerialGCExample {
    public static void main(String[] args) {
        System.out.println("GC Algorithm: " + 
            ManagementFactory.getGarbageCollectorMXBeans()
            .stream()
            .map(GarbageCollectorMXBean::getName)
            .collect(Collectors.joining(", ")));
    }
}

2.2 Parallel GC

// Parallel GC ์„ค์ •
// -XX:+UseParallelGC
// -XX:ParallelGCThreads=4
public class ParallelGCExample {
    private static final int MB = 1024 * 1024;
    
    public static void main(String[] args) {
        List<byte[]> list = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            list.add(new byte[MB]); // ๋ฉ”๋ชจ๋ฆฌ ํ• ๋‹น
        }
    }
}

2.3 G1 GC

// G1 GC ์„ค์ •
// -XX:+UseG1GC
// -XX:MaxGCPauseMillis=200
public class G1GCExample {
    public static void main(String[] args) {
        // G1 GC ๋ชจ๋‹ˆํ„ฐ๋ง
        for (GarbageCollectorMXBean gc : 
            ManagementFactory.getGarbageCollectorMXBeans()) {
            long count = gc.getCollectionCount();
            long time = gc.getCollectionTime();
            String name = gc.getName();
            System.out.printf("GC %s: %d collections, %dms%n", 
                name, count, time);
        }
    }
}

3. GC ๋ชจ๋‹ˆํ„ฐ๋ง๊ณผ ํŠœ๋‹

3.1 GC ๋กœ๊น… ์„ค์ •

# GC ๋กœ๊น… ์˜ต์…˜
-verbose:gc
-Xlog:gc*:file=gc.log
-XX:+PrintGCDetails
-XX:+PrintGCDateStamps

3.2 ๋ฉ”๋ชจ๋ฆฌ ๋ฆญ ํƒ์ง€

public class MemoryLeakDetector {
    private static final List<Object> leakyList = new ArrayList<>();
    
    public static void detectLeak() {
        MemoryMXBean memoryBean = ManagementFactory.getMemoryMXBean();
        MemoryUsage heapUsage = memoryBean.getHeapMemoryUsage();
        
        System.out.printf("Memory used: %d MB%n", 
            heapUsage.getUsed() / 1024 / 1024);
        
        if ((double) heapUsage.getUsed() / heapUsage.getMax() > 0.8) {
            System.out.println("Potential memory leak detected!");
        }
    }
}

4. ์‹ค์ œ ํŠœ๋‹ ์˜ˆ์‹œ

4.1 ํž™ ํฌ๊ธฐ ์„ค์ •

# ํž™ ํฌ๊ธฐ ์„ค์ •
-Xms4g  # ์ดˆ๊ธฐ ํž™ ํฌ๊ธฐ
-Xmx4g  # ์ตœ๋Œ€ ํž™ ํฌ๊ธฐ
-XX:MetaspaceSize=256m
-XX:MaxMetaspaceSize=256m

4.2 GC ํŠœ๋‹

# G1 GC ํŠœ๋‹
-XX:+UseG1GC
-XX:MaxGCPauseMillis=200
-XX:G1HeapRegionSize=8m
-XX:InitiatingHeapOccupancyPercent=45

๊ทผ๊ฑฐ ์ž๋ฃŒ

1. ๊ณต์‹ ๋ฌธ์„œ

2. ๊ธฐ์ˆ  ๋ฌธ์„œ

์‹ค๋ฌด ๊ด€๋ จ ์ถ”๊ฐ€ ์งˆ๋ฌธ

  1. "์‹ค์ œ ํ”„๋กœ๋•์…˜ ํ™˜๊ฒฝ์—์„œ GC ํŠœ๋‹์„ ํ•ด๋ณด์‹  ๊ฒฝํ—˜์ด ์žˆ๋‚˜์š”?"

  2. "๋ฉ”๋ชจ๋ฆฌ ๋ฆญ์„ ๋ฐœ๊ฒฌํ•˜๊ณ  ํ•ด๊ฒฐํ•œ ๊ฒฝํ—˜์„ ์„ค๋ช…ํ•ด์ฃผ์„ธ์š”."

  3. "์–ด๋–ค GC ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ ์„ ํ˜ธํ•˜์‹œ๋‚˜์š”? ๊ทธ ์ด์œ ๋Š”?"

  4. "GC ๋กœ๊ทธ๋ฅผ ์–ด๋–ป๊ฒŒ ๋ถ„์„ํ•˜์‹œ๋‚˜์š”?"

์‹ค์ œ ์‚ฌ์šฉ ์˜ˆ์‹œ

GC ๋ชจ๋‹ˆํ„ฐ๋ง ์ฝ”๋“œ

public class GCMonitor {
    public static void monitorGC() {
        List<GarbageCollectorMXBean> gcBeans = 
            ManagementFactory.getGarbageCollectorMXBeans();
        
        for (GarbageCollectorMXBean gcBean : gcBeans) {
            System.out.println(gcBean.getName());
            System.out.println("Collection Count: " + 
                gcBean.getCollectionCount());
            System.out.println("Collection Time: " + 
                gcBean.getCollectionTime() + "ms");
        }
    }
}

๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰ ๋ชจ๋‹ˆํ„ฐ๋ง

@Component
@Slf4j
public class MemoryMonitor {
    @Scheduled(fixedRate = 60000) // 1๋ถ„๋งˆ๋‹ค ์‹คํ–‰
    public void checkMemory() {
        Runtime runtime = Runtime.getRuntime();
        long totalMemory = runtime.totalMemory();
        long freeMemory = runtime.freeMemory();
        long usedMemory = totalMemory - freeMemory;
        
        log.info("Memory Usage: {}MB / {}MB", 
            usedMemory/1024/1024, 
            totalMemory/1024/1024);
    }
}

์‹ค์ œ ๋ฉด์ ‘์—์„œ๋Š” ์ด๋ก ์ ์ธ ์ง€์‹๊ณผ ํ•จ๊ป˜ GC ํŠœ๋‹ ๊ฒฝํ—˜, ๋ฉ”๋ชจ๋ฆฌ ๋ฌธ์ œ ํ•ด๊ฒฐ ๊ฒฝํ—˜, ์„ฑ๋Šฅ ์ตœ์ ํ™” ๊ฒฝํ—˜ ๋“ฑ์„ ๊ตฌ์ฒด์ ์œผ๋กœ ์„ค๋ช…ํ•˜๋Š” ๊ฒƒ์ด ์ข‹์Šต๋‹ˆ๋‹ค.

JVM์˜ ๊ฐ GC(Garbage Collection) ํ”„๋กœ์„ธ์Šค์™€ ์žฅ๋‹จ์ 

1. Serial GC

ํ”„๋กœ์„ธ์Šค

  1. Young Generation (Minor GC)

    1. Eden ์˜์—ญ์—์„œ ๊ฐ์ฒด ์ƒ์„ฑ
    2. Eden ์˜์—ญ์ด ๊ฐ€๋“ ์ฐจ๋ฉด GC ๋ฐœ์ƒ
    3. ์‚ด์•„์žˆ๋Š” ๊ฐ์ฒด๋ฅผ Survivor ์˜์—ญ์œผ๋กœ ์ด๋™
    4. Eden ์˜์—ญ์„ ๋น„์›€
    
  2. Old Generation (Major GC)

    1. Mark-Sweep-Compact ์•Œ๊ณ ๋ฆฌ์ฆ˜ ์‚ฌ์šฉ
    2. Mark: ์‚ด์•„์žˆ๋Š” ๊ฐ์ฒด ์‹๋ณ„
    3. Sweep: ์ฃฝ์€ ๊ฐ์ฒด ์ œ๊ฑฐ
    4. Compact: ์‚ด์•„์žˆ๋Š” ๊ฐ์ฒด๋“ค์„ ํ•œ์ชฝ์œผ๋กœ ๋ชจ์Œ
    

์žฅ๋‹จ์ 

  • ์žฅ์ :
    • ๋‹จ์ˆœํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ ๊ตฌํ˜„์ด ๊ฐ„๋‹จ
    • ์‹ฑ๊ธ€ ์Šค๋ ˆ๋“œ ํ™˜๊ฒฝ์—์„œ ํšจ์œจ์ 
    • ์ž‘์€ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ํšจ๊ณผ์ 
  • ๋‹จ์ :
    • Stop-the-World ์‹œ๊ฐ„์ด ๊น€
    • ๋ฉ€ํ‹ฐ์ฝ”์–ด ํ™˜๊ฒฝ์—์„œ ๋น„ํšจ์œจ์ 
    • ํฐ ํž™ ๋ฉ”๋ชจ๋ฆฌ์—์„œ ์„ฑ๋Šฅ ์ €ํ•˜

2. Parallel GC

ํ”„๋กœ์„ธ์Šค

  1. Young Generation

    1. ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— GC ์ˆ˜ํ–‰
    2. Eden ์˜์—ญ์˜ ์‚ด์•„์žˆ๋Š” ๊ฐ์ฒด๋“ค์„ ๋ณ‘๋ ฌ๋กœ Survivor๋กœ ์ด๋™
    3. ๋นˆ Eden ์˜์—ญ์„ ํ•œ ๋ฒˆ์— ๋น„์›€
    
  2. Old Generation

    1. Mark ๋‹จ๊ณ„: ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋™์‹œ์— ์‚ด์•„์žˆ๋Š” ๊ฐ์ฒด ํƒ์ƒ‰
    2. Sweep ๋‹จ๊ณ„: ๋ณ‘๋ ฌ๋กœ ์ฃฝ์€ ๊ฐ์ฒด ์ œ๊ฑฐ
    3. Compact ๋‹จ๊ณ„: ์‚ด์•„์žˆ๋Š” ๊ฐ์ฒด๋“ค์„ ๋ณ‘๋ ฌ๋กœ ์žฌ๋ฐฐ์น˜
    

์žฅ๋‹จ์ 

  • ์žฅ์ :
    • Minor GC, Major GC ๋ชจ๋‘ ๋ณ‘๋ ฌ ์ฒ˜๋ฆฌ๋กœ ๋น ๋ฅธ ์ฒ˜๋ฆฌ
    • ๋†’์€ ์ฒ˜๋ฆฌ๋Ÿ‰(Throughput)
    • ๋ฉ€ํ‹ฐ์ฝ”์–ด ํ™˜๊ฒฝ์—์„œ ํšจ์œจ์ 
  • ๋‹จ์ :
    • Stop-the-World ์‹œ๊ฐ„์€ ์—ฌ์ „ํžˆ ์กด์žฌ
    • ๋ฉ”๋ชจ๋ฆฌ์™€ CPU ์‚ฌ์šฉ๋Ÿ‰์ด ์ฆ๊ฐ€
    • ์ผ์‹œ ์ •์ง€ ์‹œ๊ฐ„์ด ์˜ˆ์ธก ๋ถˆ๊ฐ€๋Šฅ

3. CMS(Concurrent Mark Sweep) GC

ํ”„๋กœ์„ธ์Šค

1. Initial Mark (STW)
   - GC Root์—์„œ ์ง์ ‘ ์ฐธ์กฐํ•˜๋Š” ๊ฐ์ฒด๋งŒ ๋งˆํ‚น
   
2. Concurrent Mark
   - ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰๊ณผ ๋™์‹œ์— ๋งˆํ‚น
   - ์ฐธ์กฐ๋œ ๊ฐ์ฒด๋“ค์„ ์ถ”์ 
   
3. Remark (STW)
   - Concurrent Mark ๋‹จ๊ณ„์—์„œ ๋ณ€๊ฒฝ๋œ ๋ถ€๋ถ„ ํ™•์ธ
   - ์ตœ์ข… ๋งˆํ‚น ์ž‘์—…
   
4. Concurrent Sweep
   - ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰๊ณผ ๋™์‹œ์— ๊ฐ€๋น„์ง€ ์ œ๊ฑฐ

์žฅ๋‹จ์ 

  • ์žฅ์ :
    • Stop-the-World ์‹œ๊ฐ„์ด ๋งค์šฐ ์งง์Œ
    • ์‘๋‹ต ์‹œ๊ฐ„(Latency)์ด ์ค‘์š”ํ•œ ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜์— ์ ํ•ฉ
    • ์‹ค์‹œ๊ฐ„ ์ฒ˜๋ฆฌ๊ฐ€ ํ•„์š”ํ•œ ์‹œ์Šคํ…œ์— ์ ํ•ฉ
  • ๋‹จ์ :
    • CPU์™€ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์ด ๋†’์Œ
    • ๋ฉ”๋ชจ๋ฆฌ ๋‹จํŽธํ™” ๋ฌธ์ œ ๋ฐœ์ƒ
    • Compaction ๊ณผ์ •์ด ์—†์Œ

4. G1(Garbage First) GC

ํ”„๋กœ์„ธ์Šค

1. Young GC
   1) Eden ์˜์—ญ์˜ ์‚ด์•„์žˆ๋Š” ๊ฐ์ฒด๋ฅผ Survivor ์˜์—ญ์œผ๋กœ ์ด๋™
   2) ์—ฌ๋Ÿฌ ์Šค๋ ˆ๋“œ๊ฐ€ ๋ณ‘๋ ฌ๋กœ ์ž‘์—…
   
2. Mixed GC
   1) Initial Mark (STW)
      - GC Root ์Šค์บ”
   2) Concurrent Mark
      - ์ „์ฒด ํž™์˜ ์‚ด์•„์žˆ๋Š” ๊ฐ์ฒด ์ถ”์ 
   3) Remark (STW)
      - ์ตœ์ข… ๋งˆํ‚น ์ž‘์—…
   4) Cleanup (STW/Concurrent)
      - ๋นˆ ๋ฆฌ์ „ ํšŒ์ˆ˜ ๋ฐ ํšŒ์ˆ˜ํ•  ๋ฆฌ์ „ ๊ณ„์‚ฐ

์žฅ๋‹จ์ 

  • ์žฅ์ :
    • ํฐ ํž™ ๋ฉ”๋ชจ๋ฆฌ์—์„œ๋„ ํšจ์œจ์ 
    • ์˜ˆ์ธก ๊ฐ€๋Šฅํ•œ Stop-the-World ์‹œ๊ฐ„
    • ๋ฉ”๋ชจ๋ฆฌ ๋‹จํŽธํ™” ์ตœ์†Œํ™”
    • Region ๋‹จ์œ„์˜ ๋ฉ”๋ชจ๋ฆฌ ๊ด€๋ฆฌ๋กœ ์œ ์—ฐํ•จ
  • ๋‹จ์ :
    • CPU์™€ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰์ด ๋” ๋†’์Œ
    • ๋ณต์žกํ•œ ์•Œ๊ณ ๋ฆฌ์ฆ˜์œผ๋กœ ์ธํ•œ ํŠœ๋‹์˜ ์–ด๋ ค์›€
    • ์ž‘์€ ํž™์—์„œ๋Š” ์˜ค๋ฒ„ํ—ค๋“œ ๋ฐœ์ƒ

5. ZGC (Java 11+)

ํ”„๋กœ์„ธ์Šค

1. Mark Start (STW - ฮผs ๋‹จ์œ„)
   - GC Root์—์„œ ์‹œ์ž‘ํ•˜๋Š” ๊ฐ์ฒด ๋งˆํ‚น ์‹œ์ž‘

2. Concurrent Mark and Remap
   - ์• ํ”Œ๋ฆฌ์ผ€์ด์…˜ ์‹คํ–‰๊ณผ ๋™์‹œ์— ๋งˆํ‚น
   - ๋ฉ”๋ชจ๋ฆฌ ํŽ˜์ด์ง€ ์žฌ๋งคํ•‘

3. Mark End (STW - ฮผs ๋‹จ์œ„)
   - ๋งˆํ‚น ์ž‘์—… ์™„๋ฃŒ

4. Concurrent Reset and Remap
   - ๋ฉ”๋ชจ๋ฆฌ ์ •๋ฆฌ ๋ฐ ์žฌ๊ตฌ์„ฑ

์žฅ๋‹จ์ 

  • ์žฅ์ :
    • ๋งค์šฐ ์งง์€ Stop-the-World ์‹œ๊ฐ„(< 10ms)
    • ํฐ ํž™ ํฌ๊ธฐ(์ˆ˜ TB)์—์„œ๋„ ํšจ์œจ์ 
    • ๋ฉ”๋ชจ๋ฆฌ ๋‹จํŽธํ™” ๋ฌธ์ œ ํ•ด๊ฒฐ
  • ๋‹จ์ :
    • ๋” ๋†’์€ CPU์™€ ๋ฉ”๋ชจ๋ฆฌ ์‚ฌ์šฉ๋Ÿ‰
    • ์•„์ง ์•ˆ์ •ํ™” ๋‹จ๊ณ„
    • ๋ฉ”๋ชจ๋ฆฌ ์˜ค๋ฒ„ํ—ค๋“œ ์กด์žฌ

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