- android - RelativeLayout 背景可绘制重叠内容
- android - 如何链接 cpufeatures lib 以获取 native android 库?
- java - OnItemClickListener 不起作用,但 OnLongItemClickListener 在自定义 ListView 中起作用
- java - Android 文件转字符串
我正在阅读“The C# Language”,第 4 版,它讨论垃圾收集如下:
"BILL WAGNER: The following rule is an important difference between C# and other managed environments.
Prior to an application’s termination, destructor's for all of its objects that have not yet been garbage collected are called, unless such cleanup has been suppressed (by a call to the library method GC.SuppressFinalize, for example)."
所以我有几个问题:
问题 1。为什么 .net 在这里不同于其他托管环境(我想这是在暗示 Java?)?有什么特别的设计问题吗?
问题 2。调用 GC.SuppressFinalize
的对象会发生什么情况?我知道这意味着 GC 不会调用此类对象的终结器(析构函数),如果是这样,这些对象何时会真正被销毁,以便分配的内存位返回到堆中?不然会内存泄漏吗?
最佳答案
What will happened to objects that GC.SuppressFinalize is called? I understand that this means GC will not call such objects' finalizer (destructor), if so, when will these objects got really destructed? otherwise there'll be Memory Leak right?
你对finalization的用途有误解。终结是为了清理不是托管内存的资源。
假设您有一个包含整数字段的引用类型对象。该整数字段恰好是通过调用非托管代码打开文件而获得的文件句柄。
由于某些其他程序可能想要访问该文件,因此尽快关闭该文件是礼貌的做法。但是 .NET 运行时不知道这个整数对操作系统有什么特殊意义。它只是一个整数。
解决此问题的方法通常是将对象标记为实现 IDisposable,然后在完成处理后立即对该对象调用“Dispose”。然后您执行“Dispose”关闭文件。
请注意,这里没有什么特别的事情发生。清理非托管资源的方法称为“Dispose”,需要处置的对象实现 IDisposable 只是一种约定。垃圾回收对此一无所知。
那么现在问题来了:如果有人忘记调用 Dispose 怎么办?文件是否永远保持打开状态? (明明进程结束时文件会被关闭,但是进程运行时间长了怎么办?)
要解决这个问题,您可以使用终结器。它是如何工作的?
当一个对象即将被垃圾回收时,垃圾回收器会检查它是否有终结器。如果是这样,那么它不会对它进行垃圾回收,而是将它放在终结器队列中。在未来某个未指定的时间点,运行一个线程来检查队列并在每个对象上调用一个特殊的“Finalize”方法。之后,对象从终结队列中移除并标记为“嘿,我已经被终结了”。该对象现在再次符合收集条件,因此垃圾收集器最终会运行并收集该对象, 不会将其放入终结队列。
很明显,“Finalize”和“Dispose”经常需要做同样的事情。
但是现在另一个问题出现了。假设您处理一个对象。 现在不需要定稿了。 定稿很昂贵;它使死对象存活的时间比需要的时间长得多。因此,传统上处理一个对象时,Dispose 的实现不仅会关闭非托管资源,还会将该对象标记为“该对象已经被终结,不要再次终结”。这样它就可以诱使垃圾收集器不将对象放入终结队列。
那么让我们回答您的具体问题:
What will happened to objects that GC.SuppressFinalize is called?
当对象死亡时,垃圾收集器将简单地回收对象的内存,而不会将对象放入终结器队列。
I understand that this means GC will not call such objects' finalizer
GC 从不 调用终结器。终结器线程是唯一调用终结器的线程。
when will these objects got really destructed?
不清楚您所说的“破坏”是什么意思。如果您的意思是“终结器何时运行?”答案是“从不”,因为你说过要抑制最终确定。如果你的意思是“什么时候回收托管堆中的内存?”,答案是“一旦对象被垃圾收集器识别为死亡”。这将比正常情况更快发生,因为终结器队列不会使对象保持事件状态。
关于C#语言 : Garbage Collection, SuppressFinalize,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/6652044/
多次调用 GC.SuppressFinalize(object) 有什么缺点吗? protected Dispose(bool) 方法 dispose pattern 检查它之前是否被调用,但在公共(
我有几个问题无法得到正确的答案。 1) 当我们没有析构函数时,为什么要在 Dispose 函数中调用 SuppressFinalize。 2) Dispose 和 finalize 用于在对象被垃圾回
在 .NET 中 Task.Delay() 的引用源中,我遇到了 a snippet of code : // ... and create our timer and make sure that
Java 是否有相当于 .Net 的 GC.SuppressFinalize ? 在 .Net 中,SuppressFinalize 用于 dispose pattern避免 relatively h
我在实践中的观察是GC.SuppressFinalize并不总是抑制对终结器的调用。尽管如此,终结器可能还是被调用了。因此,我想知道 GC.SuppressFinalize 是否具有请求的性质,而不是
刚看完这篇文章,“Garbage Collection: Automatic Memory Management in the Microsoft .NET Framework ”,作者 Jeffre
在.NET中,什么情况下应该使用GC.SuppressFinalize()? 使用这种方法给我带来了什么好处? 最佳答案 SuppressFinalize 只能由具有终结器的类调用。它通知垃圾收集器
因为 finalizer/IDisposable 和所谓的“IDisposable 模式”主题往往会引发大量故作姿态、武断和好战的观点(不是-分别是 here 、 here 、 here 等等),我真
我可以在同一个类中实现这两个方法吗? public class MyClass : IDisposable { // some implementation // if i missed to
有没有办法检测对象是否调用了 GC.SuppressFinalize? 我有一个看起来像这样的对象(为清楚起见省略了完整的 Dispose 模式): public class ResourceWrap
我为我的代码使用默认的 IDisposable 实现模板(模式)。 片段: public void Dispose() { Dispose(true); GC.SuppressFina
出于某种原因FXCop seems to think我应该在 Dispose 中调用 GC.SuppressFinalize,无论我是否有终结器。 我错过了什么吗?是否有理由在没有定义终结器的对象上调
我正在阅读“The C# Language”,第 4 版,它讨论垃圾收集如下: "BILL WAGNER: The following rule is an important difference
是的,我知道如何使用GC.SuppressFinalize() - 解释了here .我读过很多次使用 GC.SuppressFinalize() 从终结队列中删除对象,我认为这是好的,因为它使 GC
我在使用供应商库时遇到了一些问题,有时库计算出的实体应该始终包含有效数据时为空。 功能代码(与供应商调试问题后)大致如下: Task.Factory.StartNew(() => Valida
正如问题所述,我只是想知道,因为有人问过我,但我不知道,这有任何原因吗? 最佳答案 当一个类没有定义终结器(析构函数)时,在该类的实例上调用 SuppressFinalize() has no eff
有些类(例如 DataTable)已经在其构造函数中调用了 SuppressFinalize,因此没有必要在其上调用处置/使用。 (因为dispose是为了早点release但是没有release)
我有一个简单的类 MyDataClass,其成员 (obj) 实现了 IDisposable: public class MyDataClass : IDisposable { private
我刚刚实现了 Dispose 模式,当我刚刚键入 GC.SuppressFinalize(this) 行时,我想知道是否有使用 以外的东西的用例this 作为方法的参数。 这是典型的模式: publi
我有以下代码: public void Dispose() { if (_instance != null) { _instance = null; /
我是一名优秀的程序员,十分优秀!