7月,Edward Yang写道(重点补充):
A weak pointer can also optionally be associated with a finalizer, which is run when the object is garbage collected. Haskell finalizers are not guaranteed to run.
我找不到任何证实这种说法的文件. 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,则执行终结器.
编辑:对于未来的读者:上述陈述并不完全正确. RTS产生一个单独的线程来在GC之后执行终结器.因此,程序可能会在执行GC后退出,但终止程序尚未执行,请参阅this comment.
无论如何,这在理论上是正确的.在实践中,终结器may not be executed,例如,当RTS尝试连续执行多个终结器时,其中一个抛出异常.所以我不会使用终结器,除非它是不可避免的.