数据表释放计时
本文关键字:释放 数据表 | 更新日期: 2023-09-27 18:27:04
在 C# 中,我在Form1_Load
和单击事件中都调用GC.Collect()
问题是GC.Collect()
似乎什么也没做Form_load
但在点击事件中工作。为什么?
GC.Collect()
Form1_Load
第一次
GC.Collect()
第二次click event
使用视觉工作室 2015 诊断工具
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
DataTable dt;
private void Form1_Load(object sender, EventArgs e)
{
dt = new DataTable();
dt.Columns.Add("1", typeof(int));
dt.Columns.Add("2", typeof(int));
dt.Columns.Add("3", typeof(int));
for (int i = 0; i < 1000000; i++)
{
DataRow dr = dt.NewRow();
dr[0] = 10;
dr[1] = 1000;
dr[2] = 10000;
dt.Rows.Add(dr);
}
//gc first time
dt = null;
GC.Collect();
}
private void button1_Click(object sender, EventArgs e)
{
//gc sec time
dt = null;
GC.Collect();
}
}
打电话给GC.Collect
是你能做的最糟糕的事情(大约 100% 的时间(。
GC.Collect
检查应用程序内存中对象的引用计数。由于将dt
设置为 null,因此不应再引用该DataTable
实例。好的,所以垃圾回收"收集"它。但这仅意味着它将其放在终结器队列中。您没有调用dt.Dispose
这会调用GC.SuppressFinalize(this)
来通知 gc 不需要将此对象放入终结器队列。
通过将此对象排队等待完成,将有一个新的DataTable
引用,并且该对象将向上移动一代。结果是垃圾回收将保留此内存更长时间。
通过在按钮处理程序中第二次调用GC.Collect
,会使事情变得更糟。因为同样,所有仍然引用的对象都会向上移动一代并保留更长时间。
您只需通过调用dt.Dispose
或将其括在 using 语句中来释放DataTable
:
private void Form1_Load(object sender, EventArgs e)
{
using (DataTable dt = new DataTable())
{
dt.Columns.Add("1", typeof(int));
dt.Columns.Add("2", typeof(int));
dt.Columns.Add("3", typeof(int));
//... your code
}
}
即使你这样做,也请不要打电话给GC.Collect
.让垃圾收集完成它的工作,因为它总是最知道如何做。如果需要,它将释放未使用的内存。
有关详细信息,请参阅了解 .NET 中的垃圾回收或此Microsoft文章。