我正在尝试了解您的方法。由于您没有完全提及您的策略,因此我有一些假设。
注意:以下是我的假设分析,实际上可能不太可能。因此,如果您没有时间,请跳过答案。
您正在尝试使用带有更改的 Generational GC;有2种分类
(1) 大尺寸物体BZ和
(2)小尺寸物体SZ。
SZ使用压缩(CMS)执行分代 GC
从上面的理解我们知道SZG2有长寿命的对象。我预计 szG2 中的 GC不像SZG1 或 SZG0那样频繁,因为长寿命的对象通常寿命更长,所以更少的死收集和SZG2的大小会随着时间的推移而增加失效,因此 GC 需要花费大量时间遍历所有元素,因此与SZG1 或 SZG0相比,在SZG2上进行频繁的 GC 效率较低(长时间的 GC 峰值,因此对用户来说有明显的延迟) 。
同样,对于BZ,可能需要大量内存(因为大对象占用更多空间)。所以为了解决你的查询
"The other problem occurs when the BZ is full and SZ is empty, I would be silly not be able to satisfy a big object allocation request even though we in fact have enough free heap size for the big object in SZ. How to deal with this problem?"
既然您说“当程序需要更多内存时,虚拟机将从操作系统中获得更多”
我有一个小想法,可能没有生产力或可能无法实现,并且完全取决于您对 GCHeap 结构的实现。让您的虚拟机按如下方式分配内存
下面的可能性(我从“程序的内存段”中借用了想法,如下所示)在低级别是可能的。
如上图所示,必须以SZG0和BZ相互扩展的方式定义GCHeap 结构。为了实现图 a和图 b中提到的 GCHeap 结构,我们需要在区域SZG[0 -2]大小和BZ 。
因此,如果您想将应用程序的堆划分为多个堆,那么您可以将图 A堆放在图 B上以减少碎片(当我说碎片时it means "when the BZ is full and SZ is empty, I would be silly not be able to satisfy a big object allocation request even though we in fact have enough free heap size for the big object in SZ."
)。
所以有效的结构将是
B
|
B
|
B
|
B
|
A
现在它完全取决于启发式来决定是在多个 GCHeap 结构中考虑 GCHeap 数据结构,如 GCHeapA、GCHeapB 还是根据需求将其作为单个堆。
如果您不想有多个堆,那么您可以使用图 A 并进行小幅修正Setting base address of **SZG2** to top of heap
图 a 背后的关键原因如下:我们知道SZG0经常被 GC'ed,因此与SZG1和SZG2 相比,它可以有更多的空闲空间,因为死对象被删除,幸存对象被移动到SZG1和SZG2。所以如果分配BZ越多,它就可以向SZG0增长。
在图中, SZG1和SZG2的基地址是 连续的,因为SZG2更容易出现内存不足错误,因为老一代对象往往寿命更长,而且 GC 不会扫描太多(注意:这只是我的假设和意见)所以SZG2一直向外绑定。