OCaml:Sys.max_array_length 和较小的堆大小

OCaml: Sys.max_array_length and minor heap size

在 OCaml 中,数组的大小限制为 Sys.max_array_length。由于我使用的是 64 位系统,结果大约是 2^54 - 1。但是,当我尝试

Array.make (Sys.max_array_length / 100) 0;; 

没用。具体来说,我得到了一个 Out_of_memory 异常。然后,我通过 ocamlrun 运行 看到了以下消息。

Initial minor heap size: 2048k bytes
Initial major heap size: 992k bytes
Initial space overhead: 80%
Initial max overhead: 500%
Initial heap increment: 992k bytes
Initial allocation policy: 0
Initial stack limit: 8192k bytes
No room for growing heap
Fatal error: exception Out_of_memory

然后我尝试通过

增加堆大小
export CAMLRUNPARAM='s=18014398k'

这给了我一条新消息:

Initial minor heap size: 2097152k bytes
Initial major heap size: 992k bytes
Initial space overhead: 80%
Initial max overhead: 500%
Initial heap increment: 992k bytes
Initial allocation policy: 0
Initial stack limit: 8192k bytes
No room for growing heap
Fatal error: exception Out_of_memory

事实上,我不能再增加次要堆的大小,因为它会说它无法初始化页面 table。我不确定我是否做错了什么,但似乎实际上不可能创建长度为 Sys.max_array_length - 1.

的数组

在 64 位系统上,数组中的每个条目将占用 8 个字节(比方说)。如果你想要一个 2^54 的数组,这将需要 128 PB 的地址 space。很可能您的系统不允许这么大的进程。

换句话说,不能创建那么大的数组一点也不奇怪。

很好的一点是,在 64 位系统上,Sys.max_array_length 仅根据 OCaml 数据表示的细节给出上限。这并不是说您的特定系统将支持那么大的数组。

更新

如果您实际上想弄清楚对特定系统上的数据施加的大小限制,则需要调查您正在使用的系统。在 64 位系统上,在系统变得比现在强大得多之前,您实际上不会达到 OCaml 强加的限制。 Sys.max_array_length 值在那之前并不有趣。唯一有趣的限制是您使用的系统施加的限制。

更新 2

我不知道这是否有帮助,但这是 Sys.max_array_length 的代码:

let max_array_length = (1 lsl (word_size - 10)) - 1

请注意,它根据机器的字长返回一个 常量 值。它在所有 64 位机器上总是 returns 相同的值,并且对于确定在特定情况下有多少 space 可用于特定进程完全没有用。