.Net 中的对象处置
假设我有以下类:
Class MainClass
{
private OtherClass1;
MainClass()
{
OtherClass1 = new OtherClass1();
}
void dispose()
{
OtherClass1 = null;
}
}
class OtherClass1
{
private OtherClass2;
OtherClass1()
{
OtherClass2 = new OtherClass2();
}
}
class OtherClass2
{
}
如果我实例化 MainClass 并稍后调用 dispose 方法,OtherClass1 是否会被垃圾收集(稍后)?或者我必须先清除对 OtherClass2 的引用?
Assuming i have the following classes:
Class MainClass
{
private OtherClass1;
MainClass()
{
OtherClass1 = new OtherClass1();
}
void dispose()
{
OtherClass1 = null;
}
}
class OtherClass1
{
private OtherClass2;
OtherClass1()
{
OtherClass2 = new OtherClass2();
}
}
class OtherClass2
{
}
If i instatiate MainClass and later call dispose method, does the OtherClass1 gets garbage collected (later on)? Or do i have first to clear the reference to OtherClass2?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
如果一个对象没有引用,或者它所拥有的引用来自本身没有引用的对象(等等),那么该对象将被垃圾回收。
一种可视化的方式是,垃圾收集器将遍历对象引用图,跟踪所有对象引用,记录它到达的对象(仍然从某处引用)。任何它没有到达的对象都有资格进行垃圾收集,就好像它没有到达它们那么它们就不可能被使用一样。
有关详细信息,请参阅此处(特别是“垃圾收集算法”):http: //msdn.microsoft.com/en-us/magazine/bb985010.aspx
所以是的,它有资格进行 GC。
另外,如果你有一个 dispose 方法,你真的应该实现 IDisposable。
An object will get garbage collected if it has no references, or the references it does have are from objects that themselves don't have references (and so on).
A way of visualising it, is the garbage collector will walk the object reference graph, following all object references, making a note of ones it gets to (still referenced from somewhere). Any it doesn't get to are eligible for garbage collection as if it didn't get to them then they can't possibly be used.
See here for in-depth info (particularly "The Garbage Collection Algorithm"): http://msdn.microsoft.com/en-us/magazine/bb985010.aspx
So yes, it'll be eligible to be GC'd.
Also, if you have a dispose method you really should implement
IDisposable
.在提供的代码中,您不必
null
任何内容,您可以安全地删除dispose()
,一切都会好起来的。如果您的OtherClass1 和/或OtherClass2 是托管资源,即它们实现
IDisposable
接口,那么您的代码就不够好。然后你必须链接 Dispose:In the code as provided, you don't have to
null
anything, you can safely remove yourdispose()
and all will be well.If your OtherClass1 and/or OtherClass2 are managed resources, ie they implement the
IDisposable
interface then your code is not good enough. You then will have to chain the Dispose:如果没有其他引用它,它可能在某个时候被垃圾收集。请注意,这是非确定性的,您不能依赖它在特定时间跨度内收集。
一般来说,您不必太担心这一点,.NET 中的 GC 通过设计可以毫无问题地处理循环引用等。通常不需要将字段设置为
null
。Dispose
方法通常用于以确定性方式释放非托管资源,例如数据库连接等;它不是要释放正在处理的对象的内存。If there is no other reference to it, it may at some time be garbage collected. Note that this is not deterministic, you cannot rely on it being collected in a specific timespan.
In general, you shouldn't worry too much abot this, the GC in .NET can by design handle circular references etc. without any problem. Setting fields to
null
is usually not required. TheDispose
method is usually used to release unmanaged resources, such as database connections etc. in a deterministic fashion; it's not about freeing the memory of the object being disposed.最佳实践是实现 IDisposable 接口并实现 Dispose() 方法。
在 Dispose() 中,您只需释放对象使用的资源,例如任何外部资源、COM 引用、数据库连接等。
就何时对象将被垃圾收集而言,由 .NET 引擎决定:他们经常在每个版本中更新其处理算法。
一般来说,当一个对象是孤立对象(没有变量引用它)时,它将在队列中被垃圾收集。
您可以手动调用GC.Collect();但不建议这样做,因为它会干扰 .NET 垃圾收集机制。
The best practice is to implement IDisposable interface and implementing the Dispose() method.
At Dispose(), you just release the resources used by your object such as any external resources, COM references, database connections, etc.
In terms of When the object will be garbage collected, it's up to the .NET engine to decide that as they frequently update their disposal algorithm with each release.
In general, when an object is orphan (no variable references it), it will be in the queue to be garbage collected.
You can manually call GC.Collect(); but that's not recommended since it interferes .NET garbage collection mechanism.
“Dispose”一词有点用词不当,因为 Dispose 方法不会删除目标对象,而是会请求目标对象执行任何在安全放弃之前需要执行的操作。本质上,这是对对象的请求,要求其将其事务排序。
当特定对象需要将其事务排序时,最常见的情况是当它外部的某些实体可能正在做某事、存储某事、不做某事或以其他方式暂时改变其行为时。请注意,实体可能是 .net 对象、其他类型的操作系统可识别的对象(GDI 句柄等)等,但没有特别要求实体是任何特定类型的事物,也不要求它们位于同一台计算机中,甚至任何计算机。对于一个对象来说,要使其事务井然有序,外部实体代表它做、持有等任何事情都需要被告知它们不再需要这样做。如果相关实体是实现 IDisposable 的 .net 对象,则通常通过调用其 Dispose 方法来执行通知。
请注意,.net 提供了一种方法,如果系统发现对象已被放弃,对象可以通过该方法请求通知,并使用该方法作为提示来整理其事务。此类通知可能不会及时发出,并且各种因素可能导致它们基本上无限期地延迟,但该机制(称为“最终确定”)有时总比没有好。
The term "Dispose" is a bit of a misnomer, since the Dispose method doesn't delete the targeted object but rather serves a request for the targeted object to do anything that will need to be done before it may be safely abandoned. Essentially, it's a request for the object to put its affairs in order.
The most common situation when a particular object will need to put its affairs in order is when some entities outside of it may be doing something, storing something, refraining from doing something, or otherwise temporarily altering their behavior on its behalf. Note that the entities may be .net objects, other types of OS-recognized objects (GDI handles, etc.), etc. but there's no particular requirement that the entity be any particular kind of thing, nor that they be in the same computer, or even any computer. For an object to puts its affairs in order, outside entities doing, holding, etc. anything on its behalf need to be told that they no longer need to do so. If the entities in question are .net objects that implement IDisposable, the notification would be generally performed by calling their Dispose method.
Note that .net provides a means by which objects can ask to be notified if the system notices that they've been abandoned, and use that as a cue to put their affairs in order. Such notifications may not come in timely fashion, and various factors may cause them to be delayed essentially indefinitely, but the mechanism (called "finalization") is sometimes better than nothing.