在说明垃圾回收的实现机制之前,先说明一下垃圾回收存在的背景。

垃圾回收器(GC)是.NET平台中一个很重要的组成部分,.NET垃圾回收机制降低了编写程序的复杂程度,使程序员不用耗费精力去处理析构,成功的将内存管理从程序的编写时,脱离到运行时。

一、析构函数

析构函数的作用主要是释放类在构造函数中以及类生命周期中所获取的资源,比如需要释放互斥锁、由操作符NEW所分配的对象内存等。当然析构函数也不只限于释放资源,一般析构函数可以执行在最后一次操作对象后所需要执行的任何操作。

二、关于垃圾回收

在.NET FRAMEWORK框架中,内存中的资源(二进制信息)分为“托管资源”和“非托管资源”,其中托管资源必须受到CLR的管理(如强类型安全检查),非托管资源需要手动释放。

托管资源分别存放在两个地方,一个是“堆栈”,另外一个是“托管堆”。值类型和引用类型的引用存放在“堆栈”中,而引用类型所代表的对象存在于“托管堆”中。

三、垃圾回收算法

CLR中的每个对象有两个开销字段:类型对象指针,同步块索引。

(1)、对于对象生存期的管理,有的系统采用“引用计数算法”,而对于微软的COM用的就是此算法。具体算法就是每个对象都在维护着一个内存字段,用来统计有多少个位置在使用该对象,当某一个位置不在使用该对象后,该内存字段中的计数就减一,直至该字段最后为0,当值为0时,该对象就可以从内存中删除掉了。

但是该算法最大的问题就是处理不好循环引用。

(2)、CLR使用的算法为“引用跟踪算法”,此算法只关心引用类型的变量,因为只有这种变量才能引用堆上的对象。可以将引用类型的变量称为根。

此算法是当CLR进行GC时,首先暂停所有线程,以防止线程CLR在检查期间访问对象并更改其状态。

A、CLR遍历堆中的所有对象,并将同步块索引字段中的一位设为0,这表明所有对象可以被删除。

B、查看所有活动根,并查看它们引用了哪些对象。如果一个根包括NULL,则忽略此根继续检查下一个根。

C、如果某根引用了堆上的对象,则会标记此对象,在该对象的同步块索引中的位设为1。此对象被标记后,CLR会检查这个对象中的根,标记它们引用的对象。若发现对象已经标记,则不再重新检查该对象,也就避免了因为循环引用而产生死循环。

D、检查完毕后,堆中的对象要么被标记,要么未被标记,然后CLR进入GC的“压缩”阶段。(需要注意的是,静态字段引用的对象会一直存在,直到用于加载类型的APPDOMAIN卸载为止。内在泄漏的一个重要原因就是静态字段引用某个对象集合,然后不停的向对象集合添加数据项。所以,要尽量避免使用静态字段。)

四、代的机制

CLR的GC是基于代的垃圾回收器,对于垃圾回收做了以下假设:

1、对象越新,生存期越短。

2、对象越老,生存期越长。

3、回收堆的一部分,速度快于回收整个堆。

五、垃圾回收触发条件

1、当CLR检测到第0代超过内存预算时,则触发一次GC。

2、代码显式调用GC的静态方法Collect。大多时候要避免使用此方法。从第2代开始回收。

3、当使用CreateMemoryResourceNotification或者QueryMemoryResourceNotification来监视系统的总体内存使用情况时,如果Windows报告内存低,则CLR会强制垃圾回收以释放死对象,减小进程工作集。

4、CLR卸载APPDOMAIN时,CLR会认为一切都不是根。

5、CLR正在关闭,Windows将会回收进程中的全部内存。

六、垃圾回收模式

有两种基本GC模式:工作站、服务器。应用程序默认使用以“工作站”GC模式运行。若想使用服务器回收器,可以在配置文件中添加gcServer元素(gcServer=true)。

另外还有两种子模式:并发(默认)和非并发。一般并发垃圾回收器消耗的内存通常比使用非并发垃圾回收器多。若要使用非并发回收器,可在配置文件中创建gcConcurrent元素(enable=false)

七、需要特殊清理的类型

针对一些本机资源的终结,CLR除了回收对象内存之前,还需要在Finalize中释放本机资源,如下所示:

  public class sometype()
{
~sometype()//此为一个finalize方法
}  

需要注意的是,finalize方法的执行时间是控制不了的。同时,CLR不保证多个finalize方法的调用顺序,在finalize方法中最好不要访问定义了finalize方法的其他类型的对象。调用静态方法也要小心。由于此方法是为释放本机资源而设计的,所以要谨慎使用。

如果想创建封装了本机资源的类型时,需要继承Safehandle。

另外一种释放本机资源的方法是Dispose,调用此方法只是控制这个清理动作的发生时间。同时,调用此方法并不会将托管对象从托管堆中删除。若决定显示调用Dispose方法,建议将调用放在一个异常处理finally块中。

.NET 垃圾回收浅解的更多相关文章

  1. Java虚拟机之垃圾回收详解一

    Java虚拟机之垃圾回收详解一 Java技术和JVM(Java虚拟机) 一.Java技术概述: Java是一门编程语言,是一种计算平台,是SUN公司于1995年首次发布.它是Java程序的技术基础,这 ...

  2. 基于Python对象引用、可变性和垃圾回收详解

    基于Python对象引用.可变性和垃圾回收详解 下面小编就为大家带来一篇基于Python对象引用.可变性和垃圾回收详解.小编觉得挺不错的,现在就分享给大家,也给大家做个参考. 变量不是盒子 在示例所示 ...

  3. python 垃圾回收详解

    原文:https://zhuanlan.zhihu.com/p/31150408 总纲 策略和垃圾回收系统工作内容 引用计数详解 标记-清除+分代收集 循环引用 编程应用-常见方法 ex 过程详解 使 ...

  4. C# using垃圾回收详解

    简介 定义一个范围,将在此范围之外释放一个或多个对象. 语法 using (Font font1 = new Font("Arial", 10.0f)) { } C# 语言参考 主 ...

  5. JVM垃圾回收详解

    通常,我们在写java程序的时候,似乎很少关注内存分配和垃圾回收的问题.因为,这部分工作,JVM已经帮我们自动实现了. 这样看起来,好像很美好,但是任何事情都有两面性.虽然JVM会自动的进行垃圾回收, ...

  6. Python垃圾回收详解:引用计数+标记清理+分代回收

    Python采用的是引用计数机制为主,标记-清理和分代收集两种机制为辅的策略. 1.引用计数 python中一切皆对象,所以python底层计数结构地就可以抽象为: 引用计数结构体{ 引用计数; 引用 ...

  7. JVM中GC浅解:垃圾回收的了解

    1.为什么要有GC 没有GC的世界,我们需要手动进行内存管理,但是内存管理是纯技术活,又容易出错.但是我们写码的目的是为了解决业务问题,所以可以把这种纯技术活自动化,当然自动化也是有代价的. 2.垃圾 ...

  8. Java Garbage Collection基础详解------Java 垃圾回收机制技术详解

    最近还是在找工作,在面试某移动互联网公司之前认为自己对Java的GC机制已经相当了解,其他面试官问的时候也不存在问题,直到那天该公司一个做搜索的面试官问了我GC的问题,具体就是:老年代使用的是哪中垃圾 ...

  9. JVM的垃圾回收机制详解和调优

    JVM的垃圾回收机制详解和调优 gc即垃圾收集机制是指jvm用于释放那些不再使用的对象所占用的内存.java语言并不要求jvm有gc,也没有规定gc如何工作.不过常用的jvm都有gc,而且大多数gc都 ...

随机推荐

  1. 无法启动DISTRIBUTED TRANSACTION COORDINATOR解决方法

    有时候我们需要进行COM应用程序的权限设置,控制面板-->管理工具-->组件服务-->然后依此展开:组件服务-->计算机-->我的电脑-->DCOM 配置,接下来找 ...

  2. Dreamweaver_CS6安装及破解文件

    资源下载地址: 链接: https://pan.baidu.com/s/1mhQ5DoO 密码: mnv3 1.下载,安装,先作为试用版安装 可能显示的页面不一样,但是就是安装试用版 2.接受许可协议 ...

  3. C++多线程编程一

    1.C++多线程初步: #include <iostream> #include <thread> #include <Windows.h> using names ...

  4. null、 is_null() 、empty() 、isset() PHP 判断变量是否为空

    PHP中,在判断变量是否为空的时候,总会纠结应该选用哪个函数,下面列取常用的多种情况,其中1/3经过我的验证,其它来自网络,验证后使用... 使用 PHP 函数对变量 $x 进行比较 表达式 gett ...

  5. leetcode-849-到最近的人的最大距离

    题目描述: 在一排座位( seats)中,1 代表有人坐在座位上,0 代表座位上是空的. 至少有一个空座位,且至少有一人坐在座位上. 亚历克斯希望坐在一个能够使他与离他最近的人之间的距离达到最大化的座 ...

  6. Eclipse下,修改MAVEN 中央仓库地址,解决maven下载慢问题

    作用于所有工作空间: 1.逐项打开:eclipse->preference->Maven->User Settings.按窗口中的User Settings文本框显示的路径,创建se ...

  7. 16个最佳响应式HTML5框架分享

    HTML5框架可以快速构建响应式网站,它们帮助程序员减少编码工作,减少冗余的代码.如今有很多免费的HTML5框架可供使用,由于它们有着响应式设计.跨浏览器兼容.相对轻量级等特点,这些框架在开发中都十分 ...

  8. docker相关命令

    1. 进入docker容器 ① 查看运行的容器:docker ps -a ②  进入容器:docker exec -ti [容器id] bash ③ 退出容器:eixt

  9. 1.TypeError: must be str, not bytes

    1.TypeError: must be str, not bytes错误: 解答: 写文件处 open(filename, 'w').write 应该写为 open(filename, 'wb'). ...

  10. Check类之TypeValidation

    (1)Validator类的visitTypeApply()方法 实例1: class TestTypeVal<T extends InputStream>{ TestTypeVal< ...