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----------------------------------大约持续了总时间的三分之一左右。

    程序终结,退出。

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

  • 相关阅读:
    How to convert VirtualBox vdi to KVM qcow2
    (OK)(OK) adb -s emulator-5554 shell
    (OK)(OK) using adb with a NAT'ed VM
    (OK) How to access a NAT guest from host with VirtualBox
    (OK) Creating manually one VMs from an existing VDI file in CLI (VBoxManage) in Fedora 23
    (OK)(OK) Creating VMs from an existing VDI file in CLI (VBoxManage) in Fedora 23
    (OK) Creating_VMs_from_an_existing_VDI_file.txt
    (OK) Creating VMs from an existing VDI file —— in OS X
    (OK) install_IBM_SERVER.txt
    (OK) install chrome & busybox in android-x86_64 —— uninstall chrome
  • 原文地址:https://www.cnblogs.com/zuozuo/p/2185239.html
Copyright © 2011-2022 走看看