zoukankan      html  css  js  c++  java
  • 关于GC的使用

    先看下面的代码:
    private void button1_Click(object sender, System.EventArgs e)
      {
       TestObj obj = new TestObj();
       obj.WriteSomethin( "text" );
       GC.Collect();
       GC.WaitForPendingFinalizers();
       doStuff();
      }

      private void doStuff()
      {
       for ( int n = 1;  n <= 5; n++ )
       {
        System.Threading.Thread.Sleep( 1000 ); //simulate long running operation
        System.IO.StreamWriter sw = new System.IO.StreamWriter( @"C:\Test.log", true );//append to file
        sw.WriteLine( "Iteration " + n );
        sw.Close();
       }
      }
     }

     public class TestObj : IDisposable
     {
      ~TestObj()
      {
       AllDone();
      }
      public void Dispose()
      {
       AllDone();
      }
      private void AllDone()
      {
       System.IO.StreamWriter sw = new System.IO.StreamWriter( @"C:\Test.log", true );//append to file
       sw.WriteLine( "TestObj Destroyed " + System.DateTime.Now.ToShortTimeString() );
       sw.Close();
      }
      public void WriteSomethin( string strStuff )
      {
       System.IO.StreamWriter sw = new System.IO.StreamWriter( @"C:\Test.log", true );//append to file
       sw.WriteLine( strStuff );
       sw.Close();
      }
     }

    你运行上面的代码,然后点击button1,不关闭程序,直接查看C:\Test.log,你会看到下面的内容:

    text
    Iteration 1
    Iteration 2
    Iteration 3
    Iteration 4
    Iteration 5

    看来程序没有调用析构函数,因为程序中没有出现"TestObj Destroyed"。接着关闭程序,再看一下C:\Test.log,你发现"TestObj Destroyed..."。
    实现上我们是用下面的语句触发析构函数的调用的:

     GC.Collect();
     GC.WaitForPendingFinalizers();

    究竟谁来清空“处理完成器(finalizers)队列”并触发GC去清除对象?上面的语句并没有触发对TestObj的析构函数的调用。关键的是我们不能准确控制对象将在什么时候被运行时收集。
    现在,我们增加第二个按钮并添加下面的代码:

    private void button2_Click( object sender, System.EventArgs e )
      {
       using( TestObj obj = new TestObj() )
       {
        obj.WriteSomethin( "text" );
       }
       doStuff();
      }

    重新运行程序,点击''button2",C:\Test.log出现下面的内容:

    text
    TestObj Destroyed 15:45
    Iteration 1
    Iteration 2
    Iteration 3
    Iteration 4
    Iteration 5

    再关闭程序,C:\Test.log中的内容为:

    text
    TestObj Destroyed 15:45
    Iteration 1
    Iteration 2
    Iteration 3
    Iteration 4
    Iteration 5
    TestObj Destroyed 15:45

      我们发觉出现了两处"TestObj Destroyed".这是由于我们在 ~TestObj()与Dispose()中都调用了 AllDone()。第一个"TestObj Destroyed"是由Dispose()产生的,第二是由~TestObj()产生的。在using语句结束时,对TestObj进行了清理(但我们并没有调用GC.Collect 与 GC.WaitForPendingFinalizers),调用了Dispose(),但没有调用析构函数~TestObj(),想不明白,请高手指点。
      所以,在编程中尽量避免使用GC.Collect 与 GC.WaitForPendingFinalizers,让CLR自己去管理 。

    原文来自http://dotnetjunkies.com/WebLog/grant.killian/posts/6033.aspx

  • 相关阅读:
    VSCode编写 Vue 项目标签内显示写CSS提示设置
    Vue 炫酷 Echarts 图表
    vue 动态生成拓扑图
    Vue 全局 websocket
    Vue 自定义组件v-model父子组件传值双向绑定
    vue项目Echarts更新数据是数据表展示错版
    Vue图片加载错误、图片加载失败的处理
    Vue 使用 Ant-d 简单实现左侧菜单栏和面包屑功能
    Vue Echarts图表dataZoom缩放区域根据数据量显示
    Echarts图例数据太多实现滚动效果
  • 原文地址:https://www.cnblogs.com/dudu/p/451.html
Copyright © 2011-2022 走看看