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<People> lst = new List<People>();
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----------------------------------大约持续了总时间的三分之一左右。

程序终结,退出。

不知道朋友们对这个‘垃圾回收’是否还有其他方面的认识?可否跟贴交流一下,我也跟着长长见识。先在此感谢各位跟贴的朋友。

原文地址:https://www.cnblogs.com/zuozuo/p/2185239.html