Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Java

Khác biệt giữa PermGen Space và Metaspace trong Java

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 UnloadingKhó khăn, cần Full GC, dễ leak PermGenDễ dàng hơn, class unload khi ClassLoader không còn reachable
OutOfMemoryErrorjava.lang.OutOfMemoryError: PermGen spacejava.lang.OutOfMemoryError: Metaspace
String InterningLưu trong PermGenLư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 VM.metaspace – chi tiết Metaspace usage.
  • 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:MaxMetaspaceSize và -Xmx sao 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.