(1)整体阐述
GC是垃圾回收(Garbage Collect)的缩写,它是.NET众多机制中最为重要的一部分,也是对我们的代码书写方式影响最大的机制之一。.
.NET中的垃圾回收是指清理托管堆上不会再被使用的对象内存,并且移动仍在被使用的对象使它们紧靠托管堆的一边。
(2)细节介绍
下图展示了一次垃圾回收之后托管堆上的变化(这里仅仅为了说明,简化了GC的执行过程,省略了包含Finalize方法对象的处理以及大对象分配的特殊性):
如上图所示,我们可以知道GC的执行过程分为两个基本动作:
一是找到所有不再被使用的对象:对象A和对象C,并标记为垃圾;
二是移动仍在被使用的对象:对象B和对象D。
这样之后,对象A和对象C所占用的内存空间就被腾空出来,以备下次分配的时候使用。
那么,问题来了,追问:GC在哪些情况下会进行回收工作呢?
-
内存不足溢出时(0代对象充满时)
-
Windwos(.NET Framework时代)报告内存不足时,CLR会强制执行垃圾回收
-
CLR卸载AppDomian,GC回收所有
-
调用GC.Collect
-
其他情况,如主机拒绝分配内存,物理内存不足,超出短期存活代的存段门限
(3)补充说明
通常情况下,我们不需要手动干预垃圾回收的执行,不过CLR仍然提供了一个手动执行垃圾回收的方法:GC.Collect()。当我们需要在某一批对象不再使用并且及时释放内存的时候可以调用该方法来实现。
But,垃圾回收的运行成本较高(涉及到了对象块的移动、遍历找到不再被使用的对象、很多状态变量的设置以及Finalize方法的调用等等),对性能影响也较大,因此我们在编写程序时,应该避免不必要的内存分配,也尽量减少或避免使用GC.Collect()来执行垃圾回收。
(4)背景知识
一个对象的生命周期简单概括就是:创建>使用>释放,在.NET中一个对象的生命周期:
-
new创建对象并分配内存 -
对象初始化 -
对象操作、使用 -
资源清理(非托管资源) -
GC垃圾回收