OCaml是否复制了自定义块?

Jef*_*ges 5 ocaml garbage-collection memory-management

想象一下,我有一个名为libcat的C库,用于与我蓬松的猫进行交互.因此,我正在为OCaml编写绑定,以简化与蓬松的交互.

module type CAT = sig 
   type cat
   val find : ... -> cat
   val feed : cat -> unit
   ...
end ;;
module Cat : CAT = ...
Run Code Online (Sandbox Code Playgroud)

libcat中已经内置了相当多的内存管理,例如缓存,释放被破坏的玩具,甚至可能是用于清空垃圾的有限范围的垃圾收集器.然而,整体libcat要求用户明确地释放未使用的资源,例如丢失的玩具.

我为Cat.find编写了一个C存根,它使用libcat的cat_find例程查找并分配cat,但随后将结果指针存储到使用caml_alloc_custom创建的自定义块中的cat.

我在传递给caml_alloc_custom的custom_operations结构中添加了一个finalize方法.至关重要的是,我已经完成了这个最终确定方法,因为我在回答电话异常时,她厌倦了她在门上划伤.

我现在担心,如果OCaml复制了Cat.cat类型的自定义块,那么OCaml的垃圾收集器可能会在我们还在播放时释放蓬松.例如 :

let fluffy = Cat.find ;;
fluffy.yodel ;;
let meow = fluffy ;;
...
meow.feed ;;
Run Code Online (Sandbox Code Playgroud)

我们必须假设...在最后一次明确提到蓬松之后会触发OCaML的垃圾收集器,比如打破菜肴.这个垃圾收集活动是否会调用fluffy的finalize方法并释放她?或者只是简单地提到蓬松的原始定制块,从而防止蓬松被释放?

我想在这种情况下不会释放蓬松,否则OCaml肯定会在custom_operations结构中要求一个重复的方法,但我觉得最好问一下.如果实际上可以释放蓬松,我可以通过仅让OCaml通过引用来处理她来防止这种情况吗?粗略地说:

  type cat_name = real_cat ref
  type real_cat
Run Code Online (Sandbox Code Playgroud)

Gil*_*il' 2

自定义块本身,即从 获取的字节caml_alloc_custom,是 Caml 堆的一部分,可以像任何其他对象一样移动。\xc2\xb9 自定义块包含指向也可以通过以下方式访问的数据结构的指针是很常见的: C\xc2\xb2 代码位于 Caml 堆之外;Caml将自定义块的内容视为不透明,甚至不知道它是否包含指针,因此它不会触及这些数据结构。

\n\n

当您编写 时let meow = fluffy,没有进行任何复制:您只是为同一个对象赋予一个新名称。Caml 永远不会复制自定义块;如果你想要这样,你必须copy_cat在你的库中提供一个原语。

\n\n

\xc2\xb9 \n只有次要垃圾收集器和压缩器实际上会移动块,而主要垃圾收集器则不会。但这不是您应该依赖的东西。\n

\n\n

\xc2\xb2 \n或者 Fortran,或者您的程序或库使用的任何其他语言。\n

\n