jvm-hotspot - 如何测量 Hotspot 元空间中的碎片?

标签 jvm-hotspot memory-fragmentation

我正在研究调试应用程序中的“OutOfMemoryError: Metaspace”错误。就在 OOME 之前,我在 gc 日志中看到以下内容:

{Heap before GC invocations=6104 (full 39):
 par new generation   total 943744K, used 0K [...)
  eden space 838912K,   0% used [...)
  from space 104832K,   0% used [...)
  to   space 104832K,   0% used [...)
 concurrent mark-sweep generation total 2097152K, used 624109K [...)
 Metaspace       used 352638K, capacity 487488K, committed 786432K, reserved 1775616K
  class space    used 36291K, capacity 40194K, committed 59988K, reserved 1048576K
2015-08-11T20:34:13.303+0000: 105892.129: [Full GC (Last ditch collection) 105892.129: [CMS: 624109K->623387K(2097152K), 3.4208207 secs] 624109K->623387K(3040896K), [Metaspace: 352638K->352638K(1775616K)], 3.4215100 secs] [Times: user=3.42 sys=0.00, real=3.42 secs] 
Heap after GC invocations=6105 (full 40):
 par new generation   total 943744K, used 0K [...)
  eden space 838912K,   0% used [...)
  from space 104832K,   0% used [...)
  to   space 104832K,   0% used [...)
 concurrent mark-sweep generation total 2097152K, used 623387K [...)
 Metaspace       used 352638K, capacity 487488K, committed 786432K, reserved 1775616K
  class space    used 36291K, capacity 40194K, committed 59988K, reserved 1048576K
}

据我所知,元空间容量甚至没有接近 promise 的大小(在本例中,-XX:MaxMetaspaceSize=768m)。所以我怀疑元空间的碎片导致分配器无法为新类加载器找到新 block 。

我知道 -XX:PrintFLSSatistics 但它只涵盖 CMS,不涵盖 native 内存。

所以我的问题是:Hotspot 的 native 内存是否有类似 PrintFLSSatistics 的调试帮助?

这是为 linux-amd64 JRE (1.8.0_45-b14) 使用 Java HotSpot(TM) 64 位服务器虚拟机 (25.45-b02)。

最佳答案

我刚刚研究了 HotSpot 中元空间的实现。元空间被分成 block 并使用空闲列表进行管理。所以碎片确实是你的问题的可能原因。

我还查看了 HotSpot VM 的标志 (-XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal),在发布版本中没有标志。

然而,在 Metaspace 类中有一个 dump() 方法,它似乎是通过设置 -XX:+TraceMetadataChunkAllocation 标志来触发的。还有 -XX:+TraceMetavirtualspaceAllocation 听起来您会感兴趣。但是,这些是“开发”标志,这意味着您需要 VM 的调试版本。

关于jvm-hotspot - 如何测量 Hotspot 元空间中的碎片?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/32117471/

相关文章:

Java 8 字符串重复数据删除与 String.intern()

java - 从核心转储中提取堆转储 (hprof)

c++ - 内存碎片会减慢 New/Malloc 的速度吗?

c++ - 哪种内存分配算法最适合性能和时间要求严格的 C++ 应用程序?

使用 MSMQ 异步 IO 时的 .NET 堆碎片

java - HotSpot Serviceability Agent 的 iterateObjectsOfKlass() 太慢

java - 64 位 OpenJDK 7/8 中并发长写入的值完整性保证

c++ - 避免内存碎片的方法

c++ - 自定义内存分配-C v。C++

java - 如何用 Java 编写正确的微基准测试?