简体   繁体   English

弱引用终结器保证运行

[英]Weak Reference Finalizer Guaranteed to Run

In The cost of weak pointers and finalizers in GHC , Edward Yang writes (emphasis added): Edward Yang 在《 GHC中的弱指针和终结器的代价》中写道(强调):

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. Haskell终结器无法保证运行。

I cannot find any documentation that corroborates this claim. 我找不到任何证实这一说法的文件。 The docs in System.Mem.Weak are not explicit about this. System.Mem.Weak中的文档对此并不明确。 What I need to know is, given some primitive that has identity ( MutVar# , MutableArray# , Array# , etc.), if I attach a finalizer to it, will it reliably be called when the value gets GCed? 我需要知道的是,给定一些具有标识的原语( MutVar#MutableArray#Array#等),如果我将终结器附加到该终结器,则在值被GCed时会可靠地调用它吗?

The reason is that I'm considering doing something like this: 原因是我正在考虑做这样的事情:

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

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

I want to make sure that I free the array (and everything the array points to) when an OffHeapTree goes out of scope. 我想确保在OffHeapTree超出范围时释放数组(以及数组指向的所有内容)。 Otherwise, it would leak memory. 否则,它将泄漏内存。 So, can this be reliably accomplished with mkWeakIORef or not? 那么,是否可以使用mkWeakIORef可靠地完成此操作?

"Haskell finalizers are not guaranteed to run" means that GC may not be performed (eg on program exit). “不能保证运行Haskell终结器”意味着可能不会执行GC(例如,在程序退出时)。 But if GC is performed, then finalizers are executed. 但是,如果执行了GC,则将执行终结器。

Edit: For future readers: the statement above is not exactly correct. 编辑:对于将来的读者:上面的说法并不完全正确。 RTS spawns a separate thread to execute finalizers after GC. RTS在GC之后产生一个单独的线程来执行终结器。 So the program may exit after GC is performed, but finalizers are not yet executed, see this comment . 因此,在执行GC之后,程序可能会退出,但尚未执行终结器,请参见此注释

That is true in theory anyway. 无论如何理论上都是如此。 In practice finalizer may not be executed , eg when RTS tries to execute a number of finalizers in a row, and one of then throws an exception. 实际上,终结器可能不会执行 ,例如,当RTS尝试连续执行多个终结器,然后其中一个抛出异常时。 So I'd not use finalizers unless it is unavoidable. 因此,除非不可避免,否则我不会使用终结器。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM