C#:亲自验证“垃圾回收”的整个过程

今天一朋友跑来问我,都说C#垃圾回收多么强大,它到底运行了吗?垃圾回收到底是不是真的释放着内存? 说真的,我被这话也问得一愣,C#代码是写过不少,别管是生搬硬套还是其他方法,垃圾回收的映象都是处于一个书面认识上。我从来没测试过垃圾回收到底是个什么状态,也就是说从未关心过这点。实现IDisposable接口之后,按照两种机制相配合的方式将代码实现了,就未曾注意过软件使用过程中内存的占用情况。垃圾回收到底干了没有,我没亲自观看过。
被朋友这样一问,我便写了一个最简单的代码,亲自测试了一下,并亲眼观看了程序整个的运行过程,记录了其内存的使用情况。
代码如下
1 using System; 2 using System.Collections.Generic; 3 4 namespace zuo_TestCompareProject{ 5 6 #region "程序入口" 7 public class Program{ 8 static void Main(){ 9 Console.WriteLine("填充数据"); 10 string str = Console.ReadLine(); 11 List lst = new List(); 12 for(int i=0;i<100000;i++){ 13 lst.Add(new People(String.Format("{0:000000}",i))); 14 } 15 Console.WriteLine("释放?"); 16 str = Console.ReadLine(); 17 foreach(People a in lst){ 18 //Console.WriteLine(a); //我没让它显示,挺占内存的说 19 a.Dispose(); 20 } 21 str = Console.ReadLine(); 22 } 23 } 24 #endregion 25 26 #region "垃圾收集实验类" 27 //定义一个存放人类信息的人类 28 //实现IDisposable接口 29 public class People:IDisposable 30 { 31 private string pname; 32 33 public People(string n){ 34 this.pname = n; 35 } 36 37 public override string ToString() 38 { 39 return String.Format("姓名:{0}",this.pname); 40 } 41 42 bool isPosed = false; //释放控制开关 43 public void Dispose(){ //实现接口中的方法 44 Dispose(true); 45 System.GC.SuppressFinalize(this); //手工释放过的,就不要再调用析构函数进行释放了 46 } 47 48 public virtual void Dispose(bool disposeing){ //方法重载 49 if(!isPosed){ //如果未调用过,则进入释放资源 50 51 if(disposeing){ //手工释放 52 //释放所有托管资源 53 //Console.WriteLine("释放所有托管资源。"); //我没让它显示,挺占内存的说 54 System.GC.Collect(); //强制进行垃圾回收 55 } 56 57 //释放未托管的资源,如数据库连接、文件关闭等操作 58 //Console.WriteLine("释放未托管的资源,如数据库连接、文件关闭等操作..."); //我没让它显示,挺占内存的说 59 } 60 61 isPosed = true; //已经释放过资源了 62 } 63 64 ~People(){ 65 Dispose(false); //程序员未进行手工释放,由垃圾回收自动进行 66 } 67 } 68 #endregion 69 }
创建了一个自定义的People类,在其内部实现了IDisposable接口
在Main()里面,一次性生成了10万个引用对象,此时被分配到了‘堆’上。
然后开始执行逐个对象释放过程。
观看并记录其运行情况如下:
程序一打开,处于初始化状态,此时占用的内存是:7140k
当我按下任意键,开始填充数据,整个数据填充完毕后,此时占用的内存是:14544k
开始逐个对象的调用其Dispose()方法,整个过程一开始,占用内存是:17856k
释放过程在继续,因为创建的引用对象不少,变动过一次数据,占用内存是:17884k
继续释放,过了没一会,时间不长,数据再次变动,占用内存是:14524k----------------------------从此时,看到了垃圾是工作了,释放内存了。
继续释放,这次过了好久,数据再次发生变动,占用内存是:6652k--------------------------------可以看到内存释放的很明显。
至此一直到释放完毕,一直保持着,内存占用量:6652k----------------------------------大约持续了总时间的三分之一左右。
程序终结,退出。
不知道朋友们对这个‘垃圾回收’是否还有其他方面的认识?可否跟贴交流一下,我也跟着长长见识。先在此感谢各位跟贴的朋友。
Tags: 

延伸阅读

最新评论

发表评论