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】:DataSet
和 DataTable
实际上没有任何非托管资源,因此 Dispose()
实际上并没有做太多事情。 DataSet
和 DataTable
中的 Dispose()
方法只是因为继承的副作用而存在 - 换句话说,它实际上在终结中没有做任何有用的事情。
事实证明,DataSets
、DataViews
、DataTables
在它们的构造函数中抑制了终结,这就是为什么在它们上显式调用 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
引用。 dt
和 grdView.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周。