【发布时间】:2015-06-23 17:09:40
【问题描述】:
适用于堆内和堆外分配。堆上 - 在三个主要垃圾收集器的上下文中:CMS、Parallel Old 和 G1。
目前我知道(或认为我知道)的:
- 所有对象(堆上)分配都四舍五入到 8 字节边界(或 2 的更大幂,由
-XX:ObjectAlignmentInBytes配置。 - G1
- 对于小于区域大小(1 到 32 MB,可能在 堆大小 / 2048 左右)的堆上分配,没有内部碎片,因为没有必要,因为分配器永远不会“填补漏洞”。
- 对于区域大小较大的分配,它会将分配向上舍入到区域大小。 IE。 区域大小 + 1 字节的分配很不吉利,几乎浪费了 50% 的内存。
-
对于CMS,我找到的唯一相关信息是
自然旧空间 PLAB 模仿索引空闲列表空间的结构。每个线程预先分配一定数量的每个大小小于 257 堆字的块(从全局空间分配的大块)。
来自http://blog.ragozin.info/2011/11/java-gc-hotspots-cms-promotion-buffers.html。 据我了解,所谓的“全局空间”是主要的旧空间。
问题:
- 以上说法正确吗?
- CMS 中主要旧空间的碎片属性是什么?超过“257 个堆字”的分配怎么办?
- 如何使用 Parallel Old GC 管理旧空间?
- Hotspot JVM 是使用系统内存分配器进行堆外分配,还是使用特定分配器重新管理它?
UPD。讨论帖:https://groups.google.com/forum/#!topic/mechanical-sympathy/A-RImwuiFZE
【问题讨论】:
-
为什么要这样做?请记住,这些东西从实施到实施,从更新到更新。如果您正在尝试优化,我认为最新的文章可能是您最好的选择。 2011 年已经过去了。
-
Google 是您的朋友(使用搜索工具 -> 一年内):March 2015 JVM GC Tunning Guide
-
@markspace 我在发帖前已经阅读了这篇文章。本指南未提及内部碎片。
-
关于您的第四点,查看源代码,很容易发现,在当前热点上,他们正在使用普通的 malloc 进行分配。入口点是 sun.misc.Unsafe.allocateMemory
-
老实说,我很困惑:这个问题没有一个简单的答案,但请考虑就像@markspace 所说的那样,在使用低级主题时,您应该仔细碎片化,世代安排等......这些的实现可以非常广泛地从一个版本到另一个(主要)或从一个更新到另一个版本,因此使您的实现有点在黑暗中拍摄......如果在另一端,您的问题是为了知识而知识,我也想听听专家对您的一些观点的意见!
标签: java memory-management jvm-hotspot memory-fragmentation heap-fragmentation