问题标签 [finalizer]
For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.
c# - 终结器和析构函数,维基百科怎么说?
据我了解,关于这个问题有两个阵营——第一个认为终结器是 C# 特有的析构函数。所以他们认为这两件事是一样的。
第二个阵营认为存在细微差别——在维基百科中写道——““析构函数”一词通常用于表示确定性调用的清理,而“终结器”则在垃圾收集器要求运行时运行。”
但让我为自己澄清一些事情。确定性调用的清理?在 C# 规范和 msdn 中写到不能调用析构函数(它们是自动调用的)。唯一可以自动调用它们的情况是垃圾收集器。
所以我看不出确定性调用的清理和垃圾收集器的情况有什么区别。
是这样还是不是?
c# - Visual C# 中没有析构函数?
据我了解,C# 中的析构函数语法(~ClassName)是一种编写终结器的方法。该方法编译到 IL 后成为 Finalize 方法。
因此,这意味着 C# 编程语言确实支持析构函数,但作为 .net 框架的一部分的 Visual C# 不允许程序员使用它。
编辑:我知道可以使用 IDisposable 接口来清理非托管资源。问题不在于它。问题是关于 Visual C# 中是否有析构函数?因为析构函数的语法是编写终结器的一种方式 => 没有办法定义析构函数本身。
c# - 为什么总是需要在具有 IDisposable 成员的对象上实现 IDisposable?
据我所知,如果您有一个具有 IDisposable 成员 m 的类 A,则 A 应该实现 IDisposable 并且它应该在其中调用 m.Dispose() 是一个公认的规则。
我找不到令人满意的理由。
我理解如果你有非托管资源,你应该提供一个终结器以及 IDisposable 的规则,这样如果用户没有显式调用 Dispose,终结器仍然会在 GC 期间清理。
但是,有了该规则,您似乎不需要拥有该问题所涉及的规则。例如...
如果我有一堂课:
公约规定我应该有MyImage : IDisposable
. 但是如果 Image 遵循约定,实现了一个 finalizer,而我不关心资源的及时释放,那还有什么意义呢?
更新
找到了关于我想在这里得到什么的很好的讨论。
java - 如何添加安全防护来释放应该由客户端代码显式释放的资源
用户应该调用Player.close()
以释放由本机代码管理的一些关键资源,并杀死为播放器对象创建的几个内部 java 线程。但是,用户调用它失败,导致一些资源泄漏。添加一个 Finalize 方法将不起作用,因为 finalize 不会被调用,因为内部线程还没有被杀死......
我们应该如何处理这种情况?
编辑:
我将研究幻影参考。此外,我不应该终止那些聚合线程以便玩家对象有资格获得 gc 吗?
.net - 调试时强制 Dispose()
我知道这不是标准做法,但是是否有任何缺点或更好的替代方法来执行以下操作?我只是想确保正确使用代码,而 .NET 不会为您做任何事情来确保它。
c# - 收集拥有对象时如何终止工作线程?
我有一个对象,它有一个BackgroundWorker
线程(纯粹是一个动作委托队列)。即,这是常见的、简单的单一生产者单一消费者场景。
当收集到单个生产者时,我希望它将 Terminate 动作排入BackgroundWorker
线程。
这听起来很容易——使用终结器——但这违反了“不要在终结器中触及托管资源”的规则。
那么,一旦没有更多工作要做,我如何确保线程干净地终止呢?
我宁愿不接受的答案:
IDisposable
:这将需要对基类进行大规模的重大更改,但我接受它可能是必需的(这似乎总是 IDisposable 模式的问题..)ThreadPool
: 这些都是长期运行的操作,必须按顺序运行。所以我认为专用线程是合乎逻辑的选择。WeakReference
: 刚想到这个。也许这是正确的方法(?)。基本上,线程保持WeakReference
对拥有对象的返回,并定期唤醒自己以检查它WeakReference
是否还活着,当它死亡时,它会加入一个 Terminate。不完全优雅-我不喜欢“定期唤醒自己”位-但这是最好的解决方案吗?
c# - c#:如何处理来自第 3 方库的终结器异常?
终结器总是由 .net 框架调用,因此序列可能会失控;即使构造函数失败,析构函数仍然可以被触发。
当此类终结器异常来自第三方库时,这可能会带来麻烦:我找不到处理它们的方法!
例如,在下面的代码中,虽然类 A 的构造函数总是抛出异常并失败,但 A 的终结器将由 .net 框架触发,并且由于 A 具有 B 类型的属性,所以调用 ~B()。
如果这些是我的代码,那就更容易了——我可以在终结器中使用 try-catch,至少我可以做一些日志记录——我可以允许异常使程序崩溃,尽快发现错误——或者如果我想“容忍”异常,我可以有一个 try-catch 来抑制异常,并有一个优雅的退出。
但是如果 A 和 B 是来自 3rd-party 库的类,我什么也做不了!我无法控制异常的发生,我无法捕获它们,所以我无法记录或抑制它!
我能做些什么?
java - IBM Heap Analyzer - finalize 方法
以下屏幕截图取自 IBM Heap Analyzer。
我想了解“使用 Finalize() 方法的对象数”和“实现 finalize() 方法的垃圾对象数”之间的区别。
java - 关于 Java 中终结器的问题
假设我有以下课程
在这种情况下会发生什么?调用类 A 的 finalize 方法会在某个时候被垃圾收集器调用吗?
如果垃圾收集器无论如何都会调用它,那么在子类的 finalize 方法中调用它和不调用 A 的 finalize 方法有什么区别?
在什么情况下,在子类中不调用其父类的 finalize 方法是可以的?这种情况的任何例子?
java - “终结器守护者”如何在 Java 中工作?
“终结器守护者” [Effective Java,第 30 页] 如何工作?
你用过它们吗?它解决了任何具体问题吗?