.NET垃圾回收

转载 2017年04月27日 08:38:28

.NET垃圾回收  

2009-02-09 11:50:06|  分类: 编程技术 |  标签: |举报 |字号 订阅

首先,对象分为值类型和引用类型,值类型在用完后是由操作系统自动回收的,引用类型由垃圾回收器回收,所以提到垃圾回收肯定是对引用类型来说的。

垃圾回收机制是为了解决内存泄漏问题,即对象在用完后,其占用的内存没有被释放,使一个无用的对象不必要的占用了内存,导致不正常的内存减少甚至耗尽。以前有两种内存管理技术,一种COM开发人员熟悉的引用计数技术,一种C++开发人员熟悉的Delete语句,COM开发人员会遇到循环引用的问题,C++开发人员可能忘记Delete,这都会导致内存泄漏。

垃圾回收器在两种情况下会进行回收,一是自动在适合的时间运行(如内存被耗尽,或Cpu空闲时),一种是显式调用GC.Collect()来运行。因为在运行时,它会挂起当前运行的所有线程,所以除非使用了大量的非托管资源或内存大量减少,并且此时已不再需要那些非托管资源,一次性全部释放这些资源很有意义时,才显式调用GC.Collect()。

垃圾回收器的执行过程是:

1.在new一个对象的时候,如果这个对象实现了Finallize方法,GC就会在Finallization队列放一个指向此对象的指针。

2.当垃圾回收器进行内存回收时,对于找到的每一个需要被回收的对象,会先在Finallization队列中查找是否有指向该对象的指针,如果有则将该指针移到Freachable队列,没有则直接回收。

3.当Freachable队列非空时,激活某特殊线程,逐一执行队列中每个对象的Finallize方法,然后从本队列中删除对象指针,使对象变为像没有实现Finallize方法一样(即在Finallization队列中没有指针指向它)的对象,它们将在下一次垃圾回收时进行回收。

4.按一定算法整理内存,在保证效率的情况下,使内存尽量连续。

从上面可以看到实现了Finallize方法对象比没有实现的对象在垃圾回收时效率低,所以应该尽量避免不必要的Finallize实现。

在C#中,实现Finallize的方法是使用析构函数语法,析构函数在编译时会被转换成Finallize。在Finallize方法只能释放非托管资源,因为该方法执行的时机不确定,所以当执行时,用到的托管资源可能已经被回收,如果再引用就会出错。

对于需要资源回收的对象,为了提高垃圾回收效率,应该尽量实现IDisposable接口,并在Dispose方法中调用GC.SuppressFinallize(this),把对象的指针从Finallization队列删除,来防止GC调用Finallize方法。

以下代码是推荐的实现IDispose接口的方法:

public class MyBase : IDispose

{

               private Component components;

               private IntPtr handle;

               private bool disposed;

               public void Dispose()

               {

                   if(!disposed)

                   {

                       Dispose(true);

                       GC.SuppressFinallize(this);

                   }

               }

               protected virtual void Dispose(bool disposing)

               {

                   if(!disposed)

                   {

                       if(disposing)

                       {

                           if(components!=null)

                               components.dispose();

                       }

                       CloseHandle(handle);

                       handle=IntPtr.Zero;

                       disposed=true;

                   }

               }

               public void DoSomething()

               {

                   if(disposed)

                   {

                      throw new ObjectDisposedException();

                   }

               }

               ~MyBase()

               {

                   Dispose(false);

               }

}

public class MyDerive : MyBase

{

               private ManagedResource addedManaged;

               private NativeResource addedNative;

               private bool disposed;

               protected override void Dispose(bool disposing)

               {

                   if(!disposed)

                   {

                       try

                       {

                           if(disposing)

                           {

                               if(addedManaged!=null)

                                   addedManaged.Dispose();

                           }

                           CloseHandle(addedNative);

                           disposed=true;

                       }

                       finally

                       {

                           base.Dispose(disposing);

                       }

               }

}

注意,以上代码不是线程安全的代码,如果遇到多线程,需要在if(!disposed)外层加上lock(this){}。


浅谈.NET垃圾回收

最近在做Winform项目优化,项目运行十天,内存就达到3G,真是让人头疼,到现在还没有完全解决,,,下面来说说.NET垃圾回收原理与算法 每个程序都有这样或者那样的资源,如数据库连接、网络连接、...
  • xiaoyiyz
  • xiaoyiyz
  • 2015年01月22日 11:26
  • 951

C#.Net 垃圾回收机制GC详解

C#.Net 垃圾回收机制GC详解,涉及垃圾回收机制的优点、原理、代龄、使用方法等内容。...
  • aoshilang2249
  • aoshilang2249
  • 2014年08月15日 10:10
  • 2937

深入理解.NET的垃圾回收(GC)机制

文章来源:http://www.5fire.com/rjkf/6451.htm
  • libaineu2004
  • libaineu2004
  • 2014年10月13日 22:47
  • 4428

深入了解.net垃圾回收机制之代龄与算法详解

一、代龄(Generation)   代龄就是对Heap中的对象按照存在时间长短进行分代,最短的分在第0代,最长的分在第2代,第2代中的对象往往是比较大的。Generation的层级与Fra...
  • superhoy
  • superhoy
  • 2013年01月29日 17:16
  • 950

Asp.Net中的GC(垃圾回收机制)

1.群里讨论中扯出来点,先记录下来关于GC的一些认识 建立一个测试项目。 using System; using System.Collections.Generic;...
  • itmaxin
  • itmaxin
  • 2015年01月16日 15:14
  • 1711

python,.Net,Java的垃圾回收机制

华电北风吹 天津大学计算机学院 日期:2016-08-26一、python的垃圾回收机制 1、引用计数 当一个对象的引用被创建或者复制时,对象的引用计数加1;当一个对象的引用被销毁时,对象的引...
  • zhangzhengyi03539
  • zhangzhengyi03539
  • 2016年08月26日 16:39
  • 584

关于.NET垃圾回收(GC)的基本问题

在.Net应用程序中很多问题都是没有正确的理解垃圾回收的工作原理而导致的,这里有一些关于GC的基本问题,如果看到问题答案心里都有数,那就请略过这篇,不然就一起来复习下吧。 什么是代?什么时候发生...
  • directionofear
  • directionofear
  • 2012年09月30日 15:36
  • 4316

.NET下的强制垃圾回收办法

首先谈谈其他高手的见解: .Net程序员在编程时应该怎么做,有没有一种既简单又有有效的方法来处理内存回收。愚人作以下建议,望各路高手不吝赐教:        1,对于不包涵或没有引用(直接或间接)...
  • luxiaoyu_sdc
  • luxiaoyu_sdc
  • 2011年09月01日 15:28
  • 3314

.net 垃圾回收

MSDN整理:    析构函数、Dispose()方法、Close()方法、using语句、GC.Collect...1.非托管资源    .net托管资源:由CLR管理分配和释放的资源,一般是托管内...
  • fsyiyun
  • fsyiyun
  • 2009年04月10日 10:12
  • 420

.net关于Application IIS 7回收机制

问题:应用程序池重启,导至Application_Start方法多次被调用解决:说明:调整应用程序基本设置,托管管道选择为“经典”...
  • musicrabbit
  • musicrabbit
  • 2011年01月21日 16:31
  • 1532
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:.NET垃圾回收
举报原因:
原因补充:

(最多只允许输入30个字)