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 ได้อย่างถูกต้องครับ