弱引用终结器保证 运行

Weak Reference Finalizer Guaranteed to Run

The cost of weak pointers and finalizers in GHC 中,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# 等)的原语,如果我将终结器附加到它,它是否会可靠地被调用该值得到 GCed?

原因是我正在考虑做这样的事情:

data OffHeapTree = OffHeapTree
  { ref :: IORef ()
  , nodeCount :: Int
  , nodeArray :: Ptr Node
  }

data Node = Node
  { childrenArray :: Ptr Node
  , childrenCount :: Int
  , value :: Int
  }

我想确保在 OffHeapTree 超出范围时释放数组(以及数组指向的所有内容)。否则,它会泄漏内存。那么,这是否可以通过 mkWeakIORef 可靠地完成?

"Haskell finalizers are not guaranteed to run" 表示可能不执行 GC(例如在程序退出时)。但是如果执行了GC,那么finalizers就会被执行。

编辑: 对于未来的读者:上面的说法并不完全正确。 RTS 在 GC 之后生成一个单独的线程来执行终结器。所以GC执行完后程序可能会退出,但是finalizers还没有执行,见this comment.

不管怎么说,这在理论上是正确的。在实践中终结器 may not be executed,例如当 RTS 尝试连续执行多个终结器时,其中一个抛出异常。所以除非不可避免,否则我不会使用终结器。