.net 垃圾回收

    .Net所指的托管只是针对内存这一个方面,并不是对于所有的资源;因此对于Stream,数据库的连接,GDI+的相关对象,还有Com对象等等,这些资源并不是受到.Net管理而统称为非托管资源。而对于内存的释放和回收,系统提供了GC-Garbage Collector,而至于其他资源则需要手动进行释放。

那么第二个概念就是什么是垃圾,通过我以前的文章,会了解到.Net类型分为两大类,一个就是值类型,另一个就是引用类型。前者是分配在栈上,并不需要GC回收;后者是分配在堆上,因此它的内存释放和回收需要通过GC来完成。GC的全称为“Garbage Collector”,顾名思义就是垃圾回收器,那么只有被称为垃圾的对象才能被GC回收。也就是说,一个引用类型对象所占用的内存需要被GC回收,需要先成为垃圾。那么.Net如何判定一个引用类型对象是垃圾呢,.Net的判断很简单,只要判定此对象或者其包含的子对象没有任何引用是有效的,那么系统就认为它是垃圾。

明确了这两个基本概念,接下来说说GC的运作方式以及其的功能。内存的释放和回收需要伴随着程序的运行,因此系统为GC安排了独立的线程。那么GC的工作大致是,查询内存中对象是否成为垃圾,然后对垃圾进行释放和回收。那么对于GC对于内存回收采取了一定的优先算法进行轮循回收内存资源。其次,对于内存中的垃圾分为两种,一种是需要调用对象的析构函数,另一种是不需要调用的。GC对于前者的回收需要通过两步完成,第一步是调用对象的析构函数,第二步是回收内存,但是要注意这两步不是在GC一次轮循完成,即需要两次轮循;相对于后者,则只是回收内存而已。

.Net提供了三种方法,也是最常见的三种,析构函数,Dispose方法,Close方法。

       经过前面的介绍,可以知道析构函数只能被GC来调用的,那么无法确定它什么时候被调用,因此用它作为资源的释放并不是很合理,因为资源释放不及时;但是为了防止资源泄漏,毕竟它会被GC调用,因此析构函数可以作为一个补救方法。

     而Close与Dispose这两种方法的区别在于,调用完了对象的Close方法后,此对象有可能被重新进行使用;而Dispose方法来说,此对象所占有的资源需要被标记为无用了,也就是此对象被销毁了,不能再被使用。例如,常见SqlConnection这个类,当调用完Close方法后,可以通过Open重新打开数据库连接,当彻底不用这个对象了就可以调用Dispose方法来标记此对象无用,等待GC回收。 

 

 

1.垃圾回收通知

    公共语言运行时执行的完整垃圾回收有时可能会对性能产生负面影响。对于处理大量请求的服务器而言,这个问题尤为突出;

    在这种情况下,长时间的垃圾回收可能会导致请求超时。若要防止在重要时间段发生完整垃圾回收,可以让系统通知您即将发生完整垃圾回收,然后您可以采取措施将工作负荷重定向到其他服务器实例。您也可以在当前服务器实例不需要处理请求时自己引发回收。

    注:仅当禁用并发垃圾回收时才能使用此功能。默认情况下会启用并发垃圾回收,除非您在宿主环境中运行应用程序且宿主已为您更改了该配置。在使用服务器垃圾回收时,并发垃圾回收不可用。此功能不支持并发垃圾回收,原因是在进行并发垃圾回收期间允许进行内存分配。有关如何禁用并发垃圾回收的信息,请参见 <gcConcurrent> 运行时设置。

2.如何禁用并发垃圾回收

    公共语言运行时 (CLR) 可以在单独的线程上或在与应用程序相同的线程上同时运行垃圾回收。使用 <gcConcurrent> 元素来指定运行时应如何运行垃圾回收。下面演示了如何禁用并发垃圾回收。

    <configuration>
      <runtime>
       <gcConcurrent enabled="false"/>
      </runtime>
    </configuration>

    默认情况下,运行时同时运行垃圾回收,这会降低性能。如果应用程序是单线程的并且涉及大量的用户交互,请将并发垃圾回收保留为启用,以便该应用程序不会为执行垃圾回收而暂停。如果是 ASP.NET 服务器应用程序,则不需要改变 <gcConcurrent> 元素的默认值。

 

 

 

 

你可能感兴趣的:(.net)