Datatable.Dispose() 会使其从内存中删除吗?

Posted

技术标签:

【中文标题】Datatable.Dispose() 会使其从内存中删除吗?【英文标题】:Datatable.Dispose() will make it remove from memory? 【发布时间】:2013-09-23 00:38:31 【问题描述】:

我已经通过非常简单的代码进行了研究,并且一直停留在查看数据表的 dispose() 结果

下面是代码

DataTable dt= new Datatable();
SqlCommand Cmd = new SqlCommand("sp_getData",SqlCon);
SqlCommand.CommandType= CommandType.StroedProcedure;
SqlCon.Open();
sqlDataReader dr=  cmd.ExecuteReader();
dt.Load(dr);
SqlCon.Close();
grdView.DataSource =dt;
dt.Dispose() // Here I dispose the table as it is no use for me & wanna memory free from this

但在处理掉数据表后,我仍然发现它仍然显示 RowCount = 10k。

Dispose() 方法不会释放内存并将对象设为 null 吗??

如何将其设为 null 或释放该对象占用的内存??

【问题讨论】:

这能回答你的问题吗? Should I Dispose() DataSet and DataTable? 注意建议的副本 - 接受的答案只是指其他问题... 【参考方案1】:

DataSetDataTable 实际上没有任何非托管资源,因此 Dispose() 实际上并没有做太多事情。 DataSetDataTable 中的 Dispose() 方法只是因为继承的副作用而存在 - 换句话说,它实际上在终结中没有做任何有用的事情。

事实证明,DataSetsDataViewsDataTables 在它们的构造函数中抑制了终结,这就是为什么在它们上显式调用 Dispose() 没有任何作用。

大概是因为,如上所述,它们没有非托管资源;因此,尽管MarshalByValueComponent 允许使用非托管资源,但这些特定的实现不需要,因此可以放弃最终确定。

this Immense Answer概述:

毫无疑问,应该对任何 Finalizable 对象调用 Dispose。

DataTables 是可终结的。

调用 Dispose 显着加快了内存的回收速度。

MarshalByValueComponent 在其Dispose() 中调用GC.SuppressFinalize(this) - 跳过这意味着在回收内存之前必须等待数十个甚至数百个Gen0 集合。

进一步阅读:

请参阅this question 和相关的answer。

【讨论】:

谢谢,答案令人困惑。结论是什么? 无论如何都要打电话给Dispose(),但它什么也没做。本质上,不需要对对象使用 dispise。【参考方案2】:

Dispose() 方法是否不会释放内存并将对象设为 空??

Dispose 并且处置模式不是用于回收托管内存或“删除”托管对象(您不能做的事情以及垃圾收集器的用途),它用于处理非托管资源的处置/释放或具有可发布项的其他托管资源,例如SqlConnection。它当然不会null引用,但可能会使其在处置前无法使用。

我怎样才能使它为空或释放它占用的内存 对象??

如果您想使引用为空,只需 dt = null 即可,尽管此 不会 给您带来任何好处,因为 DataTable 实例由 grdView.DataSource 引用。 dtgrdView.DataSource 都将引用相同的底层 DataTable 实例。

我还怀疑这是方法的一部分,在这种情况下,dt 无论如何都是方法范围的。

您不必为这些事情担心太多。我会更担心将SqlConnection 放在try-finally / using 之外,你有可能在那里打开连接。

我倾向于在实现IDisposable 的项目上调用Dispose,因为我认为这是一个非常很好的理由:这是公共合同。是否调用它是一个实现细节,并且可能随时更改


顺便说一句,我会完全重写你的代码:
var dt = new Datatable();

using (var conn = new SqlConnection(""))
using (var comm = new SqlCommand("sp_getData", conn))

    conn.Open();

    using (var reader = comm.ExecuteReader())
    
        dt.Load(reader);
    


grdView.DataSource = dt;

【讨论】:

如果我将其设为 dt=null,gridview 仍然表现良好.. 将其设为 null 并释放内存是个好习惯吗?? @Rajeev 我认为在您完成的项目上调用Dispose 是一个好习惯,但是,您已将DataTable 分配给DataSource,所以您不希望打电话给Dispose,因为它还没有完成。很少需要显式清空项目。 我不是在询问是否调用 Dispose() 方法,而是通过调用 dt = null 将其设为 null。在这种情况下,Gridview 仍然表现良好,我的记忆也得到释放 @RajeevKumar 您只释放了一个引用(4 或 8 个字节),grdView.DataSource 属性中仍然存在底层的 10k 行。无论如何null如果你已经完成了它,但我只是说我很少需要明确地这样做。 我正在尝试寻找解决方案,因为我的应用程序在一段时间后崩溃说system.outofmemory Exception【参考方案3】:

尝试使用 Clear() 函数。它非常适合我处理。

DataTable dt = GetDataSchema();
//populate dt, do whatever...
dt.Clear();

【讨论】:

以上是关于Datatable.Dispose() 会使其从内存中删除吗?的主要内容,如果未能解决你的问题,请参考以下文章

我想启动 UBER/LYFT 应用程序以使其从我的应用程序进入前台

如何在SQL查询中编写一个日期范围的代码,使其从当前日期向前追溯3周,并从当前日期向前追溯1周。

*为啥*列表赋值会使其左侧变平?

为啥在 subView 中添加 UILabel 会使其像素化

为啥将我的模块分成多个文件会使其变慢?

如果我在不同的线程上同步运行,它是不是会使其总体异步?