为什么 OCaml 需要创建自己的堆来进行垃圾回收?

Why does OCaml need to create its own heaps for garbage collection?

根据 this OCaml 的内存包含在由 OCaml 运行时管理的两个连续的虚拟内存块中。我想知道为什么这是必要的。难道 OCaml 不能简单地使用系统 malloc 来分配内存,并且只使用这些堆来存储块头和指向对象在内存中的实际位置的指针吗?当操作系统可以代替做这么多工作时,这似乎是对轮子的重新发明。

我还想知道为什么 OCaml 必须在垃圾收集的 compact 阶段 (source here) 分配一个全新的主堆,例如:

在下面的草图中,让字母 A-D 代表大小相同的 OCaml 块,让 . 代表释放的 space相同的大小。据我了解,OCaml 垃圾收集器将 "compact" 这个主要堆:

[AAABB..CCCCCC.....DDD....]

通过分配一个新的主堆:

[.........................]

并在释放原始堆之前将仍然存在的块复制到其中:

[AAABBCCCCCCDDD...........]

这比简单地重新排列原始堆中的这些块有何效率?在上面的示例中,连续性检查完全可以避免移动块 AB,并且在任何情况下,如何更有效地要求操作系统 总是分配一个全新的主堆?

出于性能原因,每个垃圾收集器都处理自己的堆。 malloc 非常慢,与 OCaml 次要堆分配相比,它慢了多个数量级(次要堆中的分配是在 2 条汇编指令中完成的)。

对于压缩,不,不重新分配。