Java Memory Management: Heap, Stack, Garbage Collection

#java13 เม.ย. 2569

Java Memory Model

Java จัดการ memory อัตโนมัติผ่าน Garbage Collector ทำให้ developer ไม่ต้อง free memory เอง แต่ต้องเข้าใจ memory model เพื่อเขียนโค้ดที่มีประสิทธิภาพ

Stack vs Heap

Stack:
- เก็บ local variables และ method calls
- LIFO (Last In First Out)
- เร็วมาก
- ขนาดจำกัด (StackOverflowError)
- Thread-specific

Heap:
- เก็บ Objects
- ขนาดใหญ่กว่า
- Garbage Collected
- Shared ระหว่าง threads

ตัวอย่าง

public void example() {
    int x = 5;              // Stack
    String s = "hello";     // s อยู่ Stack, "hello" อยู่ String Pool (Heap)
    Person p = new Person(); // p อยู่ Stack, Person object อยู่ Heap
}
// เมื่อ method จบ x, s, p ถูกลบจาก Stack
// Person object รอ GC

Garbage Collection

// Object ที่ไม่มี reference จะถูก GC
Person p = new Person("สมชาย");
p = null;  // Person object พร้อมถูก GC

// Circular reference - GC จัดการได้
class Node {
    Node next;
}
Node a = new Node();
Node b = new Node();
a.next = b;
b.next = a;
a = null;
b = null;
// ทั้ง a และ b พร้อมถูก GC

GC Algorithms

G1GC (default Java 9+):
- แบ่ง Heap เป็น regions
- Predictable pause times
- เหมาะกับ large heap

ZGC (Java 15+):
- Low latency < 1ms
- เหมาะกับ real-time systems

Shenandoah:
- Concurrent GC
- Low pause times

JVM Flags

# กำหนด Heap size
java -Xms512m -Xmx2g MyApp

# ใช้ G1GC
java -XX:+UseG1GC MyApp

# ใช้ ZGC
java -XX:+UseZGC MyApp

# GC logging
java -Xlog:gc* MyApp

Memory Leak

// ❌ Memory Leak - static collection ที่ไม่ถูกลบ
public class Cache {
    private static Map<String, Object> cache = new HashMap<>();

    public static void add(String key, Object value) {
        cache.put(key, value);  // ไม่มีการลบ!
    }
}

// ✅ ใช้ WeakHashMap หรือ LRU Cache
private static Map<String, Object> cache = new WeakHashMap<>();
// หรือ
private static Map<String, Object> cache = Collections.synchronizedMap(
    new LinkedHashMap<>(100, 0.75f, true) {
        protected boolean removeEldestEntry(Map.Entry eldest) {
            return size() > 100;
        }
    }
);

Profiling

# VisualVM
jvisualvm

# JConsole
jconsole

# Heap dump
jmap -dump:format=b,file=heap.hprof <pid>

สรุป

การเข้าใจ Java Memory Management ช่วยให้เขียนโค้ดที่มีประสิทธิภาพ หลีกเลี่ยง memory leak และ tune JVM ได้อย่างถูกต้องครับ