简体   繁体   English

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

[英]Datatable.Dispose() will make it remove from memory?

I have researching through very simple code and get stuck on seeing the dispose() result of datatable 我通过非常简单的代码进行研究,并且一直看到数据表的dispose()结果

Following is the code 以下是代码

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

But after disposing off the datatable i still found that it is still showing RowCount = 10k. 但在处理掉数据表之后我仍然发现它仍然显示RowCount = 10k。

Does Dispose() method does not free up the memory & make object as null ?? Dispose()方法是不是释放内存并使对象为null?

How can i make it as null or free up the memory occupied by this object ?? 我怎样才能使它成为null或释放这个对象占用的内存?

DataSet and DataTable don't actually have any unmanaged resources, so Dispose() doesn't actually do much. DataSetDataTable实际上没有任何非托管资源,因此Dispose()实际上并没有做太多。 The Dispose() methods in DataSet and DataTable exists ONLY because of side effect of inheritance - in other words, it doesn't actually do anything useful in the finalization. DataSetDataTableDispose()方法仅存在,因为继承的副作用 - 换句话说,它实际上并没有在最终化中做任何有用的事情。

It turns out that DataSets , DataViews , DataTables suppress finalization in their constructorsc this is why calling Dispose() on them explicitly does nothing. 事实证明, DataSetsDataViewsDataTables在其构造函数中抑制了最终化,这就是为什么在它们上显式调用Dispose()什么也不做。

Presumably, this happens because, as mentioned above, they don't have unmanaged resources; 据推测,这是因为,如上所述,他们没有非托管资源; so despite the fact that MarshalByValueComponent makes allowances for unmanaged resources, these particular implementations don't have the need and can therefore forgo finalization. 因此,尽管MarshalByValueComponent允许非托管资源,但这些特定实现并不需要,因此可以放弃最终确定。

Overview of this Immense Answer : 这个巨大的答案概述:

Without a doubt, Dispose should be called on any Finalizable objects. 毫无疑问,应该在任何Finalizable对象上调用Dispose。

DataTables are Finalizable. DataTables是Finalizable。

Calling Dispose significantly speeds up the reclaiming of memory. 调用Dispose可以显着加快内存的回收速度。

MarshalByValueComponent calls GC.SuppressFinalize(this) in its Dispose() - skipping this means having to wait for dozens if not hundreds of Gen0 collections before memory is reclaimed. MarshalByValueComponent在其Dispose()调用GC.SuppressFinalize(this) - 跳过这意味着在回收内存之前必须等待数十个(如果不是数百个) Gen0集合。

Further Reading: 进一步阅读:

See this question and the related answer . 看到这个问题和相关的答案

Does Dispose() method does not free up the memory & make object as null ?? Dispose()方法是不是释放内存并使对象为null?

Dispose and the disposal pattern is not for reclaiming managed memory or "deleting" managed objects (both things you cannot do and what the Garbage Collector is there for), it is for handling the disposal/release of unmanaged resources or other managed resources that have releasable items, such as SqlConnection . Dispose和处置模式不是用于回收托管内存或“删除”托管对象(您不能做的事情和垃圾收集器的用途),它用于处理非托管资源或其他托管资源的处理/释放可释放的项目,例如SqlConnection It certainly won't null the reference, but may make it unusable from the time of disposal forwards. 肯定不会使引用null ,但可能会使其从处置转发时起无法使用。

How can i make it as null or free up the memory occupied by this object ?? 我怎样才能使它成为null或释放这个对象占用的内存?

If you want to null the reference, simply dt = null will work, though this will not give you any benefit as the DataTable instance is referenced by grdView.DataSource . 如果你想使引用为空,只需dt = null即可,但是这不会给你带来任何好处,因为grdView.DataSource引用了DataTable实例。 Both dt and grdView.DataSource will be references to the same underlying DataTable instance. dtgrdView.DataSource都将引用同一个底层DataTable实例。

I also suspect this is part of a method in which case dt is method-scoped anyway. 我还怀疑这是方法的一部分,其中dt无论如何都是方法范围的。

You shouldn't have to worry too much about any of this stuff. 你不应该过分担心这些东西。 I'd be more concerned about having the SqlConnection outside of a try-finally / using , you are at risk of leaving a connection open there. 我更关心在try-finally / using之外using SqlConnection ,你有可能在那里打开一个连接。

I tend to favour calling Dispose on items that implement IDisposable for what I think is a very good reason: this is the public contract . 我倾向于赞成呼吁Dispose上实现项目IDisposable什么,我认为这是一个很好的理由:这是公共合同 The fact of whether calling it does anything or not is an implementation detail and is liable to change at a moments notice. 调用它是否有效的事实是一个实现细节 ,并且可能会立即发生变化


As an aside, I would completely re-write your code: 顺便说一句,我会完全重写你的代码:

 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; 

Try to use Clear() function. 尝试使用Clear()函数。 It works great for me for disposing. 这对我来说非常适合处置。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM