在 The cost of weak pointers and finalizers in GHC 中,Edward Yang 写道(强调):
我找不到任何证实这一说法的文件。 System.Mem.Weak
中的文档对此没有明确说明。我需要知道的是,给定一些具有标识的原语( MutVar#
、 MutableArray#
、 Array#
等),如果我给它附加一个终结器,当值被 GC 时它会被可靠地调用吗?
原因是我正在考虑做这样的事情:
data OffHeapTree = OffHeapTree
{ ref :: IORef ()
, nodeCount :: Int
, nodeArray :: Ptr Node
}
data Node = Node
{ childrenArray :: Ptr Node
, childrenCount :: Int
, value :: Int
}
我想确保在
OffHeapTree
超出范围时释放数组(以及数组指向的所有内容)。否则,它会泄漏内存。那么,这是否可以通过 mkWeakIORef
可靠地完成? 最佳答案
“不保证 Haskell 终结器运行”意味着可能不会执行 GC(例如在程序退出时)。但是如果执行 GC,则执行终结器。
编辑: 对于 future 的读者:上述陈述并不完全正确。 RTS 在 GC 之后产生一个单独的线程来执行终结器。所以程序可能会在 GC 执行后退出,但 finalizers 尚未执行,参见 this comment 。
无论如何,这在理论上是正确的。在实践中终结器 may not be executed ,例如当 RTS 尝试连续执行多个终结器,然后其中一个抛出异常时。所以除非不可避免,否则我不会使用终结器。
关于haskell - 弱引用终结器保证运行,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/45081817/