数据表配置时间

时间:2015-12-17 07:07:02

标签: c# datatable dispose

在C#中,我在GC.Collect()和点击事件

中调用Form1_Load

问题GC.Collect()似乎在Form_load

中没有做任何事情

但适用于点击事件。为什么?

GC.Collect() first time inForm1_Load

GC.Collect() second time inclick event

使用visual studio 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();
            }
    }

1 个答案:

答案 0 :(得分:2)

致电GC.Collect是您可以做的最糟糕的事情(大约100%的时间)。

GC.Collect检查应用程序内存中对象的引用计数。由于您将dt设置为null,因此不应再引用该DataTable实例。好的,所以垃圾收集“收集”它。但这只意味着它将它放在终结器队列中。你没有调用dt.Dispose来调用GC.SuppressFinalize(this)来通知gc这个对象不需要放在终结器队列上。

通过将此对象排队以进行最终化,有一个对DataTable的新引用,并且该对象向上移动了一代。结果是垃圾收集将使这个内存更长。

通过在按钮处理程序中第二次调用GC.Collect,你会让事情变得更糟。因为,所有仍然引用的对象都会向上移动一代并保持更长时间。

您应该通过调用DataTable或将其封装在using语句中来简单地处置dt.Dispose

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。让垃圾收集工作,因为它总是知道如何做到这一点。如果需要,它将释放未使用的内存。

有关详细信息,请参阅Understanding Garbage Collection in .NETthis MSDN article