我很抱歉,如果这个问题的答案是微不足道的。 但是,我还是不能由我自己弄清楚这一点。
如何在.NET中的垃圾收集器识别堆上有哪些对象是垃圾,哪些对象是不是?
比方说,一个.NET应用程序运行,并且在时间垃圾收集的某点出现(让离开了世代并且为简化起见终止队列)。
现在,应用程序可能有:
- 堆指着堆对象变量。
- 含有上堆对象的地址寄存器。
- 静态变量指着堆对象。
这是我的假设GC作品。
- 它解引用每一个这样的地址,并在堆上的对象结束。
- 它标志着对象作为垃圾不(通过使用同步块索引),因为一些变量仍然指向它。
- 它为所有地址进行此项操作(在大多数文章被称为根出于某种原因)
- 现在,因为.NET运行时具有大约每个对象的类型的信息,它可以计算每个对象的大小,并因此堆存储器的占用块。 对于所有的标记的对象,它留下的占用内存,因为它是块。
- 内存的其余部分被释放,压实和根据需要的其它物品被重新定位(及其地址更新)。
我在我的理解是否正确?
你是对的在某些情况下。 该GC看起来通过堆悲观地 - 即它衬托承担一切(第0代)将GCed。
它的字面通过对堆一切通过所谓的“标记”第一次扫描中,这是检查是否有任何引用是它去。 因为都是引用类型和一些参考其他人,这将递归浏览引用。 别担心 - 有逻辑,不进入无限循环!
如果它找到的对象不被引用,它会首先将其标记,通过设置一个标志内的对象称为同步块的索引。
通过在堆中的每个对象准备后,将然后开始一个名为“压缩”,这是当它改变所有剩余对象到存储器相同的区域,留下上述明确的存储器的过程。 因为它们是统计上更可能在同一时间取消引用它将会继续同代的对象组合在一起。
因此,这将减少所需的内存。
垃圾收集并不一定加快你的程序,但允许其重新使用未使用的对象所占用的空间。
有很多关于这个主题的文章。 我个人比较喜欢“通过C#CLR”通过杰弗里里希特谁给了它是如何工作的优秀篇章。
我目前正在读这本书 ,以帮助在垃圾收集在我的大学的独立研究项目。 如果你真的想了解的插件和奏垃圾收集的,我建议你阅读这本书,因为它似乎是周围最好的之一。 这极有可能包含了比你要寻找的更多信息,但如果你想写在未来一个垃圾收集器可能会有所帮助。
“垃圾收集”是由垃圾收集器是CLR在.NET框架的一部分来执行。
其通过识别对象腾出存储器的自动过程不再需要不同于C,C ++,其中程序员显式不得不释放内存。
如何垃圾收集工作
它定期查看内存即托管堆中,并释放被死对象占用的内存。
如果它是你的代码无法访问的死物体被识别。
履行
有3种方法中,你可以实现内存管理: -
GC仅适用于管理的资源,因此.NET提供处置和完成释放非托管资源像流,数据库连接,COM对象等。
1)配置
处置必须为其实现IDisposable类型的明确要求。
程序员必须调用这个或者使用的Dispose()或通过使用构建
使用GC.SuppressFinalize(this)来防止调用终结,如果你已经使用的Dispose()
2)完成或解构子
它是隐式调用后对象符合清理,终结的对象被称为依次终结器线程。
实施终结的缺点是,它存储器回收被延迟作为终结用于这种类/类型必须被调用之前清理,所以一个额外的colect回收内存。
3)所以GC.Collect()
使用GC.Collect的()不一定把GC收集,GC仍然可以覆盖和运行时就是了。
所以GC.Collect也()将只运行垃圾收集的跟踪部分和项目添加到队列终结,但不叫终结的类型,即由另一个线程处理。
如果你想确保所有的终结已经callled你调用GC.Collect的后使用WaitForPendingFinalizers()
请参阅张贴在我的博客,我对这篇文章有: - 垃圾收集在.NET