关于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
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】凌霞软件回馈社区,博客园 & 1Panel & Halo 联合会员上线
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】博客园社区专享云产品让利特惠,阿里云新客6.5折上折
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 一个奇形怪状的面试题:Bean中的CHM要不要加volatile?
· [.NET]调用本地 Deepseek 模型
· 一个费力不讨好的项目,让我损失了近一半的绩效!
· .NET Core 托管堆内存泄露/CPU异常的常见思路
· PostgreSQL 和 SQL Server 在统计信息维护中的关键差异
· DeepSeek “源神”启动!「GitHub 热点速览」
· 我与微信审核的“相爱相杀”看个人小程序副业
· 微软正式发布.NET 10 Preview 1:开启下一代开发框架新篇章
· C# 集成 DeepSeek 模型实现 AI 私有化(本地部署与 API 调用教程)
· spring官宣接入deepseek,真的太香了~