【问题标题】:Debugging excess GC time in ocaml在 ocaml 中调试多余的 GC 时间
【发布时间】:2020-10-07 22:44:29
【问题描述】:

我已经编写了 B 树的 OCaml 实现。它很慢,添加大约 100k 个 ~16 字节的小记录大约需要 1 分钟。当我对实现进行概要分析时,我发现该程序将大部分时间(约 58 秒)用于垃圾收集。

具体功能有:

   caml_garbage_collection, which consumes 58 seconds, of this:

   caml_major_collection_slice consumes 63% and
   caml_gc_dispatch consumes 23.5%

这种过度活跃的垃圾收集可能是什么原因造成的,我将如何调试它?

【问题讨论】:

  • 你是如何进行分析的?根据我的经验,标准的 Unix 分析工具不能很好地处理高阶函数。

标签: performance garbage-collection ocaml profiling


【解决方案1】:

我最终通过使用 OCaml 的内存分析器 Spacetime 并按照此处的说明解决了这个问题:https://blog.janestreet.com/a-brief-trip-through-spacetime/

这是一次非常顺利的体验。我发现问题是调试数据结构。我保留了一个条目列表作为对列表的可变引用,我将其更新如下:

t.orig_items <- new_entry :: t.orig_items

当您执行此操作时,OCaml 似乎会创建原始列表的副本。因此,以这种方式使用可变列表似乎是个坏主意。

【讨论】:

  • OCaml 中没有可变列表这样的东西。您在这里拥有的是一个不可变列表,您将其分配给可变记录字段。此外,在将项目添加到列表之前,就像您在此处所做的那样,确实分配了一个新的 cons 单元格,它会重用列表的其余部分(因为它是不可变的)。因此,这不会导致任何垃圾被收集,所以我怀疑这个操作具体是问题所在。我相信您在其他地方会以其他方式使用此列表,这很可能是有问题的,但这本身不应该。
  • 抱歉,我说错了,我的意思是对列表的可变引用。编辑。
猜你喜欢
  • 2013-03-22
  • 2014-08-15
  • 2021-02-28
  • 1970-01-01
  • 1970-01-01
  • 2015-11-29
  • 2018-08-06
  • 1970-01-01
  • 2014-11-04
相关资源
最近更新 更多