我正在尝试了解您的方法。由于您没有完全提及您的策略,因此我有一些假设。
注意:以下是我的假设分析,实际上可能不太可能。因此,如果您没有时间,请跳过答案。
您正在尝试使用带有更改的 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 结构的实现。让您的虚拟机按如下方式分配内存
![在此处输入图像描述](https://i.stack.imgur.com/4Rnvv.png)
下面的可能性(我从“程序的内存段”中借用了想法,如下所示)在低级别是可能的。
![在此处输入图像描述](https://i.stack.imgur.com/bgAwq.gif)
如上图所示,必须以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一直向外绑定。