gpt4 book ai didi

memory-management - OCaml 是否曾经复制过自定义 block ?

转载 作者:行者123 更新时间:2023-12-04 07:50:40 24 4
gpt4 key购买 nike

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

module type CAT = sig 
type cat
val find : ... -> cat
val feed : cat -> unit
...
end ;;
module Cat : CAT = ...

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

我为 Cat.find 编写了一个 C stub ,它使用 libcat 的 cat_find 例程查找并分配猫,然后将生成的指向猫的指针存储在使用 caml_alloc_custom 创建的自定义 block 中。

我在传递给 caml_alloc_custom 的 custom_operations 结构中添加了一个 finalize 方法。至关重要的是,我已经让这个 finalize 方法释放了猫,因为我厌倦了她在我接听电话异常时抓着门。

我现在担心,如果 OCaml 复制了 Cat.cat 类型的自定义 block ,那么 OCaml 的垃圾收集器可能会在我们还在玩的时候释放蓬松的东西。例如 :
let fluffy = Cat.find ;;
fluffy.yodel ;;
let meow = fluffy ;;
...
meow.feed ;;

我们必须假设 ... 将在最后一次显式引用 fluffy 之后触发 OCaML 的垃圾收集器,比如打碎盘子。这个垃圾回收事件会调用fluffy的finalize方法并释放她吗?或者meow会简单引用fluffy原来的自定义 block ,从而阻止fluffy被释放?

我想 fluffy 在这种情况下不会被释放,否则 OCaml 肯定会在 custom_operations 结构中要求一个重复的方法,但我觉得最好问一下。如果 fluffy 实际上可以被释放,我可以通过仅让 OCaml 通过引用处理她来防止这种情况吗?大致 :
  type cat_name = real_cat ref
type real_cat

最佳答案

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

当你写 let meow = fluffy ,没有副本发生:你只是给同一个对象一个新名称。 Caml 永远不会复制自定义 block ;如果需要,您必须提供 copy_cat图书馆中的原始人。

¹
只有次要垃圾收集器和压缩器实际移动 block ,主要 gc 不会。但这不是你应该依赖的东西。

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

关于memory-management - OCaml 是否曾经复制过自定义 block ?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5363597/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com