zoukankan      html  css  js  c++  java
  • 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----------------------------------大约持续了总时间的三分之一左右。

    程序终结,退出。

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

  • 相关阅读:
    Git基本操作二
    Git基本操作一
    Mysql查询一
    接口的token验证
    Laravel模型的一些小技巧
    AOP编程思想实现全局异常处理
    5.4 RegExp类型
    5.4.1 RegExp实例属性
    5.4.2 RegExp实例方法
    5.4.3 RegExp构造函数属性
  • 原文地址:https://www.cnblogs.com/zuozuo/p/2185239.html
Copyright © 2011-2022 走看看