PermGen (Permanent Generation) và Metaspace là vùng nhớ lưu trữ metadata của class (class definitions, methods, annotations, static variables, constant pool, v.v.). Metaspace thay thế PermGen từ Java 8.
Bảng so sánh
| Tiêu chí | PermGen (Java ≤ 7) | Metaspace (Java 8+) |
|---|---|---|
| Vị trí bộ nhớ | Trong Heap (JVM managed heap) | Native Memory (OS memory, ngoài Heap) |
| Kích thước mặc định | ~64 MB (32-bit), ~82 MB (64-bit) | Không giới hạn mặc định (tự động mở rộng) |
| Tuning flags | -XX:PermSize, -XX:MaxPermSize | -XX:MetaspaceSize, -XX:MaxMetaspaceSize |
| Class Unloading | Khó khăn, cần Full GC, dễ leak PermGen | Dễ dàng hơn, class unload khi ClassLoader không còn reachable |
| OutOfMemoryError | java.lang.OutOfMemoryError: PermGen space | java.lang.OutOfMemoryError: Metaspace |
| String Interning | Lưu trong PermGen | Lưu trong Heap (từ Java 7u40+) |
| Lý do thay đổi | - | |
| Tránh OOM PermGen khó dự đoán, tách metadata ra native memory để GC quản lý tốt hơn, hỗ trợ dynamic class loading/unloading (OSGi, hot reload, containers). | ||
Cấu hình Metaspace
# Giới hạn tối đa Metaspace (khuyên dùng set limit tránh ăn hết RAM host) -XX:MaxMetaspaceSize=256m # Kích thước khởi tạo (trigger GC khi vượt quá) -XX:MetaspaceSize=128m # Giám sát -XX:+PrintClassHistogram -XX:+PrintGCDetails
Monitoring Metaspace
jcmd– chi tiết Metaspace usage.VM.metaspace jstat -gc– cột MC (Metaspace capacity), MU (Metaspace used).- JMX:
java.lang:type=MemoryPool,name=Metaspace. - Tools: VisualVM, JConsole, Grafana + Prometheus (JMX Exporter).
Class Loading/Unloading trong Metaspace
- Class được load bởi
ClassLoader. Metadata lưu trong Metaspace gắn với ClassLoader. - Khi ClassLoader bị GC (không còn strong reference), các class đã load bởi nó cũng bị unload → Metaspace giải phóng.
- Đây là cơ chế quan trọng cho: Application servers (Tomcat, Jetty), OSGi, Spring DevTools, HotSwap.
Lưu ý vận hành
- Metaspace nằm ở Native Memory → tổng RAM container = Heap + Metaspace + CodeCache + ThreadStacks + Direct Memory + Overhead. Cần set
-XX:MaxMetaspaceSizevà-Xmxsao cho tổng < container limit. - Class loader leak (ví dụ: ThreadLocal, static cache, JDBC driver không deregister) → Metaspace tăng không kiểm soát → OOM.
- String interning (
String.intern()) từ Java 7u40+ lưu ở Heap, không còn ảnh hưởng Metaspace.