ocaml - 我应该怎么做才能让 GC 释放 OCaml 中未使用的内存?

标签 ocaml

我正在为归并排序和快速排序做一个基准测试。

我实现了 Random_list.create , Mergesort.sort_listQuicksort.sort_list .我们可以假设这三个函数被正确实现,并且实现在这个问题中并不重要。

我想问的是关于OCaml的GC .

这是我的基准代码:

let _ = 
  let l = Random_list.create 10000000 in

  let len1 = List.length (Mergesort.sort_list l) in
  Printf.printf "mergesort done for %d elements" len1;

  let len2 = List.length (Quicksort.sort_list l) in
  Printf.printf "quicksort done for %d elements" len2

如果我运行上面的代码,它会告诉我 Fatal error: exception Out_of_memory之后 mergesort done for 10000000 elements .

内存不足,没问题。输出也告诉我 Out_of_memory成功后发生mergesort .

然后我所做的是拆分代码并分别测试:
let _ = 
      let l = Random_list.create 10000000 in
      let len1 = List.length (Mergesort.sort_list l) in
      Printf.printf "mergesort done for %d elements" len1

进而
let _ = 
      let l = Random_list.create 10000000 in
      let len2 = List.length (Quicksort.sort_list l) in
      Printf.printf "quicksort done for %d elements" len2

两者都可以在没有 Out_of_memory 的情况下正常运行.

这是我的问题:

根据我的基准代码,是的,我进行了串行排序:合并排序,然后是快速排序。

在执行过程中,应该创建了 3 个主要列表:l以及来自合并排序的列表和来自快速排序的列表。

但是,从合并排序创建的列表应该是 GCed在快速排序之前,对吧?那个列表没有任何引用,对吧?

在quicksort之前,只有一个主要列表是原始l , 对?

为什么它仍然给出 Out_of_memory错误?

最佳答案

我认为问题在于您使用的是非常大的列表。垃圾收集器保留两个不同的堆来管理内存:

  • 小/短命对象的小堆。
  • 持久对象的主要堆。

  • 次要堆会定期清除,如果对象存活时间足够长,则将其提升到主要堆。

    然而,真正大的对象会直接进入主堆。问题是主堆需要停止世界,即停止应用程序。因此,主要堆收集分几个步骤完成,以确保应用程序不会长时间停止,并且不像次要堆收集那样经常完成。

    也许在您的情况下,当您开始快速排序时,merge_sort 列表仍未收集,因此所有 3 个列表同时存在于内存中。

    您可以要求 GC 进行完整的主要收集以查看是否可以解决问题:
    let _ = 
      let l = Random_list.create 10000000 in
    
      let len1 = List.length (Mergesort.sort_list l) in
      Printf.printf "mergesort done for %d elements" len1;
    
      Gc.full_major ();
    
      let len2 = List.length (Quicksort.sort_list l) in
      Printf.printf "quicksort done for %d elements" len2
    

    关于ocaml - 我应该怎么做才能让 GC 释放 OCaml 中未使用的内存?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17726321/

    相关文章:

    types - 双重强制什么时候有用?

    .net - F# 中 OCaml 的 set_signal 等效项

    parsing - OCaml 中的 Packrat 解析(通过惰性内存)

    arrays - OCaml 中的 "Break"for 循环

    regex - 使用正则表达式匹配 Ocaml 中的精确字符串

    ocaml - 如何从 OCaml 的 for 循环中获取值

    list - OCaml功能帮助涉及解析列表列表

    algorithm - ocamlgraph中的Goldberg算法可以用于查找最小成本流图吗?

    algorithm - 二叉搜索树中序遍历的无环函数算法

    object - OCaml 中是否支持 "hooks"?