了解Hotspot JVM进程的内部碎片属性

时间:2015-06-23 17:09:41

标签: java memory-management jvm-hotspot memory-fragmentation heap-fragmentation

用于堆上和堆外分配。在堆上 - 在三个主要垃圾收集器的上下文中:CMS,Parallel Old和G1。

目前我所知道的(或者我认为我知道):

  • 所有对象(堆上)分配都向上舍入到8个字节边界(或更大的2的幂,由-XX:ObjectAlignmentInBytes配置。
  • G1
    • 对于小于区域大小的堆上分配(1到32 MB,可能在堆大小 / 2048周围),没有内部碎片,因为没有必要,因为分配器从不& #34;填补空洞"。
    • 对于区域大小较大的分配,它会将分配舍入到区域大小。 I. e。分配区域大小+ 1字节是非常不吉利的,它浪费了近50%的内存。
  • 对于CMS,我找到的唯一相关信息是

      

    自然旧空间PLAB模仿索引空闲列表空间的结构。每个线程预先分配每个大小的特定数量的块,低于257个堆字(从全局空间分配的大块)。

    来自http://blog.ragozin.info/2011/11/java-gc-hotspots-cms-promotion-buffers.html。 据我所知,提到了#34;全球空间"是主要的旧空间。

问题:

  • 以上陈述是否正确?
  • CMS中主要旧空间的碎片属性是什么?分配超过" 257堆字"?
  • 怎么样?
  • 如何使用Parallel Old GC管理旧空间?
  • Hotspot JVM是否使用系统内存分配器进行堆外分配,还是使用特定分配器重新管理它?

UPD。讨论主题:https://groups.google.com/forum/#!topic/mechanical-sympathy/A-RImwuiFZE

1 个答案:

答案 0 :(得分:5)

  • 据我所知,上述陈述是正确的,虽然CMS上的一些内容缺少很多解释它的背景。
  • CMS容易碎片化(在旧的空间,CMS运行的地方),这是它的主要缺陷之一。如果它碎片过多,它可能偶尔会停止世界并进行完整标记,扫描和压缩以消除碎片,这会导致应用程序出现大幅​​停顿。正是这个缺陷经常被引用为G1开发的原因。一些系统(例如HBase)故意用固定大小的块进行大部分分配,以防止或显着减少CMS的碎片,以避免长时间停止世界停顿。
  • ParallelOldGC(或旧版GC'一般而言)不会碎片化。对象被保留到旧堆中,当它用完空间时,运行完整的标记,扫描,紧凑循环。它可以比任何其他分配器更快地完成此GC,但每2 GB堆的典型运行时间为1秒,对于大型堆或延迟敏感的应用程序来说,这可能太长了。
  • Hotspot根据目的使用了各种策略进行堆外分配。分配本机字节缓冲区不同于它自己对编译代码或分析数据的分配。我无法在这里回答有关任何细节的权限,但我只能假设其中大部分不使用系统分配器,否则Hotspot的性能不如它。此外,有一些参数可以调整以控制这个空间中的一些,例如, -XX:ReservedCodeCacheSize,它表明这样的内存区域是通过间接管理而不是直接通过系统分配器来管理的。简而言之,如果系统分配器直接用于热点中的任何细粒度分配,我会感到非常惊讶。