繁体   English   中英

.net CLR相关问题

[英].net CLR related question

这是一个与.net CLR相关的问题。

我有3个对象A,B,C

A引用B,B引用c

如果我明确地杀死对象“ A”,堆中的这些对象会发生什么。将对哪些对象进行垃圾回收?(对象A或B或c或全部?)

有人可以详细解释这种情况下的垃圾收集过程。

预先感谢SNA

首先-您不能“明确杀死对象“ A””; 您可以清除对其的引用,但这只是将局部变量设置为null ,而与托管堆上的实际对象无关。 您可以使用Dispose() ,但这与GC 无关

一切取决于; 还能看到B / C吗? 如果没有,则有资格领取 但是GC是不确定的。 它只会在选择时发生。 不确定的时间,GC将启动,检测到这些对象不可达,然后将其删除。 在此过程中,它将检查所有具有终结器(仍未完成)的对象,并执行终结器(分两步进行)。

人们经常在可及性方面忘记的一件事是事件。 如果B / C订阅了一个长期对象上的事件,则B / C是可到达的(由事件发布者)。


澄清; GC通过从根对象 (线程等)构建树来工作。 它遍历每个引用 ,标记所有可以到达的对象。 末尾未标记的任何内容都可以收集。 这避免了由于数据孤岛(X => Y和Y => X)而导致的内存泄漏而导致的COM / COM +问题(X和Y都具有正的引用计数,因此都不会清除)。

第一个误解可能是您无法明确杀死托管对象。

您可以释放自己分配的非托管内存,但这些内存不是托管的,因此也不会进行垃圾回收。

当您将对A的引用设置为null或超出范围时,将不会对B&C进行任何引用,下一个GC集合将予以解决。

在.NET中,没有办法真正杀死/删除对象。 您唯一可以做的就是分配一个对象。 这仅是对对象的Dispose()的简单调用。 这将使您可以清理对象,然后再由垃圾回收器收集对象(这样您就不会真正的无用)。 有关更多详细信息,请参见IDisposable 在GC收集对象之前有机会清理对象的第二种选择是实现终结器 与Dispose()不同,GC将自动调用它。 同样,两者都是在对象可能不存在之前清理所有资源的方法。

因此,要回答您的问题,是否仅当对象A不再被其他对象引用时才会发生“杀死”,而如果B和C仅通过A进行引用,B和C就会被“杀死”。通常,您没有任何影响力何时实际发生。 您所能做的就是实现终结器,以便在事件发生时得到通知。 GC是一项后台服务,它在单独的线程上运行,该线程在实际删除对象时遵循复杂的逻辑。

如果您想对GC的工作原理有一个基本的了解,建议您参考以下两篇 文章 尽管有些陈旧,但它们仍然完全适用。

暂无
暂无

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

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