首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何测量Hotspot的Metaspace中的碎片?

如何测量Hotspot的Metaspace中的碎片?
EN

Stack Overflow用户
提问于 2015-08-20 11:49:38
回答 2查看 742关注 0票数 3

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

代码语言:javascript
复制
{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
}

据我所见,Metaspace的容量甚至没有接近提交的大小(在本例中,是-XX:MaxMetaspaceSize=768m)。因此,我怀疑Metaspace的碎片会导致分配程序无法为新的类加载器找到新的块。

我知道-XX:PrintFLSStatistics,但这只涉及CMS,而不是本机内存。

因此,我的问题是:对于Hotspot的本机内存,是否有类似于PrintFLSStatistics的调试帮助?

这是在LinuxAMD64JRE (1.8.0_45-b14)中使用HotSpot(TM) 64位服务器VM (25.45-b02)。

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2015-08-20 12:12:43

我刚刚研究了HotSpot中Metaspace的实现。Metaspace被分成几块,并使用自由职业者进行管理。因此,碎片化确实是造成问题的一个可能原因。

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

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

票数 4
EN

Stack Overflow用户

发布于 2015-08-20 18:06:28

@loonytune的答案工作得很好,但我想提供一些更详细的信息:

对于上下文,“Metaspace”是一个元类集合,每个类加载器一个。每个元空间都包含一个VirtualSpace对象列表,其中分配了不同大小的Metachunk。这些块包含MetaBlocks,它们是元数据的真正容器。

我需要一个调试JRE来运行这些标志,所以在这位导师之后,我签出了openjdk存储库(我将签出重命名为vm,因为构建脚本似乎与jdk8文件夹名有问题)。

代码语言:javascript
复制
~/vm$ bash configure --enable-debug
~/vm$ DISABLE_HOTSPOT_OS_VERSION_CHECK=ok make all

并使用得到的vm/build/linux-x86_64-normal-server-fastdebug/images/j2re-image作为我的java运行时。

生成的日志行如下所示:

VirtualSpaceNode::take_from_committed()没有可用的8192字空间@0x00007F4cdb9350 128 K,94%使用[0x00007fedf5e22000,0x00007fedf5f13000,0x00007fedf5f22000,0x00007fedf6022000]

它表示当前VirtualSpace已满,无法容纳所请求的8192 word大小的另一个块。这将导致这个元应用程序切换到另一个VirtualSpace

ChunkManager::chunk_freelist_allocate: 0x00007F4c0c39f8块0x00007F15397400大小128计数0免费块共计7680计数15 ChunkManager::chunk_freelist_allocate: 0x00007F4c0c39f8块0x00007fedf6021000大小512计数14自由块总数7168计数14

当分配了一个新的Metachunk时,就会发生这种情况,在第一种情况下,它的长度为128个字,并且耗尽了小块的列表。如您所见,下一个请求转到中等大小的块(大小为512),总共留下14个块空闲。一旦空闲总数达到0,就需要一个完整的GC来增加总的Metaspace大小。

请注意,指定-verbose将使您从上述两个标志获得更多的输出。

票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/32117471

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档