Memory management OCaml是否复制过自定义块?

Memory management OCaml是否复制过自定义块?,memory-management,garbage-collection,ocaml,Memory Management,Garbage Collection,Ocaml,假设我有一个名为libcat的C库,用于与我的猫fluffy交互。因此,我正在为OCaml编写绑定,以简化与fluffy的交互 module type CAT = sig type cat val find : ... -> cat val feed : cat -> unit ... end ;; module Cat : CAT = ... libcat中已经内置了相当多的内存管理,比如缓存、释放被破坏的玩具,甚至可能还有一个用于清空垃圾的有限范围垃圾

假设我有一个名为libcat的C库,用于与我的猫fluffy交互。因此,我正在为OCaml编写绑定,以简化与fluffy的交互

module type CAT = sig 
   type cat
   val find : ... -> cat
   val feed : cat -> unit
   ...
end ;;
module Cat : CAT = ...
libcat中已经内置了相当多的内存管理,比如缓存、释放被破坏的玩具,甚至可能还有一个用于清空垃圾的有限范围垃圾收集器。然而,总体而言,libcat要求用户明确释放未使用的资源,比如丢失的玩具

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

我已经将finalize方法添加到传递到caml_alloc_custom的custom_operations结构中。关键的是,我让这只猫自由了,因为我讨厌她在我接电话时抓门

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

let fluffy = Cat.find ;;
fluffy.yodel ;;
let meow = fluffy ;;
...
meow.feed ;;
我们必须假定。。。将在最后一次显式引用fluffy后触发OCaML的垃圾收集器,例如通过打碎盘子。这个垃圾收集事件会调用fluffy的finalize方法并释放她吗?或者meow只是引用fluffy的原始自定义块,从而阻止fluffy被释放

我想fluffy在这种情况下不会被释放,否则OCaml肯定会在custom_operations struct中请求一个重复的方法,但我觉得这样做更好。如果fluffy实际上可能被释放,我是否可以通过只让OCaml通过引用来处理她来防止这种情况?大致:

  type cat_name = real_cat ref
  type real_cat

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

当您编写
let meow=fluffy
时,没有复制:您只是给同一对象赋予了一个新名称。Caml永远不会复制自定义块;如果需要,必须在库中提供一个
copy\u cat
原语

⑨ 只有次要的垃圾收集器和压缩程序实际移动块,而主要的gc则没有。但这不是你应该依赖的。

² 或Fortran,或您的程序或库使用的任何其他语言。