C#语言:垃圾收集,燮pressFinalize [英] C# language: Garbage Collection, SuppressFinalize

查看:169
本文介绍了C#语言:垃圾收集,燮pressFinalize的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在看C#语言,第4版,它谈论垃圾收集如下:

  

BILL WAGNER:下面的规则是C#和其他托管环境之间的一个重要区别

     

在此之前的应用程序的终止,析构函数的所有的对象还没有被垃圾回收是所谓的,除非这样的清理工作已燮pressed(通过调用库方法GC.Sup pressFinalize例如)

所以,我有几个问题在这里:

  • Q1。为什么.NET是从其他托管环境中(我想这是暗示的Java?)这里有什么不同?有什么特别的设计问题?

  • Q2。什么会发生在对象 GC.Sup pressFinalize 被称为? 我明白这意味着GC不会把这种对象的终结器(析构函数),如果是的话,什么时候这些对象得到了真正的破坏,使所分配的内存位返回到堆?否则就会有内存泄漏?

解决方案
  

怎么会发生在对象GC.Sup pressFinalize叫?我明白这意味着GC不会把这种对象的终结器(析构函数),如果是的话,什么时候这些对象得到了真正的破坏?否则就会有内存泄漏吧?

您已经定稿是一个误解。最后确定是清理那些的没有的管理内存资源。

假设你有一个包含一个整数字段引用类型的对象。这整型字段恰好是一个句柄是通过调用非托管code打开该文件获得的文件。

由于一些其他程序可能需要访问该文件,这是礼貌尽快关闭该文件。但.NET运行时不知道这个整数有什么特殊含义的操作系统。这只是一个整数。

您解决这个问题的方法通常是你将对象标记为实现IDisposable接口,然后调用该对象的处置只要你用它做。你实行处置,然后关闭该文件。

请注意,有没有什么特别的地方。这仅仅是一个的来清理非托管资源的方法被称为处置惯例和对象,需要处置实现IDisposable。垃圾收集知道绝对没有这件事。

所以,现在的问题就出现了:如果有人忘记调用Dispose?请问该文件保持开放的永远的? (显然,该文件将在这个过程结束,但如果该进程运行很长一段时间被关闭?)

要解决这个问题,你用一个终结。这是如何工作的?

当一个对象时被垃圾收集,垃圾收集器会检查它,看它是否有一个终结。如果确实如此,那么,而不是垃圾收集,它把它放在终结的队列。在将来,它检查队列,并调用每一个对象在一个特殊的定格方法的线程运行的一些不确定的一点。在此之后,对象从终结队列中删除,并标记为哎,我已经被定型。该对象现在再次eligable的集合,所以垃圾收集器最终运行并收集对象的没有的把它放在终结队列。

显然,定格和处置经常需要做同样的事情。

但现在的另一个的问题就出现了。假设你处理的对象。的现在它并不需要被最后确定的终结是昂贵。它让一个死物存活更长的时间比它需要。因此,传统上,当一个处置的对象,处置的实施不仅关闭非托管资源,这也标志着作为对象这个对象已经被定型,不要再定稿。这样,它的技巧垃圾收集到不把对象的终结队列。

因此​​,让我们回答您的具体问题:

  

怎么会发生这GC.Sup pressFinalize被称为对象?

当对象是死的垃圾收集器将简单地回收对象的内存不把对象的终结队列中。

  

据我所知,这意味着GC不会把这种对象的终结

在GC的永远的呼叫终结。终结线程调用终结的唯一的事。

  

在将这些对象得到了真正的破坏?

目前尚不清楚你所说的破坏的意思。如果你的意思是何时才能终结跑?答案是从来没有,因为你说的晚饭preSS定稿。如果你的意思是当将在托管堆中的内存被回收?,答案是只要对象被确定为死亡的垃圾收集器。这会发生的的比正常的,因为对象将不会被维持生命的终结队列。

I'm reading "The C# Language", 4th Edition, it talks about garbage collection as below:

"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)."

So I have a couple of questions here:

  • Q1. Why .net is different from other managed environments (I suppose this is hinting Java?) here? Any particular design concern?

  • Q2. 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 destroyed, so that the allocated memory bits are returned to the heap? Otherwise there'll be Memory Leak?

解决方案

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?

You have a misunderstanding of what finalization is for. Finalization is for cleaning up resources that are not managed memory.

Suppose you have an object of reference type that contains an integer field. That integer field just happens to be a handle to a file that was obtained by calling into unmanaged code to open the file.

Since some other program might want to access that file, it is polite to close the file as soon as possible. But the .NET runtime has no idea that this integer has any special meaning to the operating system. It's just an integer.

The way you solve this problem typically is you mark the object as implementing IDisposable, and then you call "Dispose" on the object as soon as you're done with it. Your implementation of "Dispose" then closes the file.

Note that there is nothing special going on here. It is just a convention that a method that cleans up an unmanaged resource is called "Dispose" and an object that needs to be disposed implements IDisposable. The garbage collection knows absolutely nothing about this.

So now the problem arises: what if someone forgets to call Dispose? Does the file stay open forever? (Clearly the file will be closed when the process ends, but what if the process runs for a long time?)

To solve this problem, you use a finalizer. How does that work?

When an object is about to be garbage collected, the garbage collector checks it to see if it has a finalizer. If it does, then instead of garbage collecting it, it puts it on the finalizer queue. At some unspecified point in the future, a thread runs that examines the queue and calls a special "Finalize" method on every object. After that, the object is removed from the finalization queue and marked as "hey, I've already been finalized". The object is now once again eligable for collection, and so the garbage collector eventually runs and collects the object without putting it on the finalization queue.

Clearly "Finalize" and "Dispose" frequently need to do the same thing.

But now another problem arises. Suppose you dispose an object. Now it does not need to be finalized. Finalization is expensive; it keeps a dead object alive for much longer than it needs to be. Therefore, traditionally when one disposes an object, the implementation of Dispose not only closes the unmanaged resource, it also marks the object as "this object has already been finalized, don't finalize it again". That way it tricks the garbage collector into not putting the object on the finalization queue.

So let's answer your specific questions:

What will happened to objects that GC.SuppressFinalize is called?

When the object is dead the garbage collector will simply reclaim the memory of the object without putting the object on the finalizer queue.

I understand that this means GC will not call such objects' finalizer

The GC never calls a finalizer. The finalizer thread is the only thing that calls finalizers.

when will these objects got really destructed?

It is not clear what you mean by "destructed". If you mean "when will the finalizers run?" the answer is "never" because you said to suppress finalization. If you mean "when will the memory in the managed heap be reclaimed?", the answer is "as soon as the object is identified as dead by the garbage collector". That will happen sooner than normal because the object will not be kept alive by the finalizer queue.

这篇关于C#语言:垃圾收集,燮pressFinalize的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆