我通过非常简单的代码进行研究,并且一直看到数据表的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或释放此对象占用的内存?
答案 0 :(得分:17)
DataSet
和DataTable
实际上没有任何非托管资源,因此Dispose()
实际上并没有做太多。 Dispose()
和DataSet
中的DataTable
方法仅因为继承的副作用而存在 - 换句话说,它实际上并没有在最终确定中做任何有用的事情。
事实证明,DataSets
,DataViews
,DataTables
会抑制其构造函数中的最终化,这就是为什么在它们上面调用Dispose()
明确无效的原因。
据推测,这是因为,如上所述,他们没有非托管资源;因此尽管MarshalByValueComponent
允许非托管资源,但这些特定实现没有必要,因此可以放弃最终确定。
毫无疑问,应该在任何Finalizable对象上调用Dispose。
DataTables是Finalizable。
调用Dispose可显着加快回收内存的速度。
MarshalByValueComponent
在其GC.SuppressFinalize(this)
中调用Dispose()
- 跳过这意味着在回收内存之前必须等待数十个(如果不是数百个)Gen0
个集合。
进一步阅读:
请参阅this question和相关的answer。
答案 1 :(得分:7)
Dispose()方法是不会释放内存和放大器。使对象成为 null ??
Dispose
并且处理模式不是用于回收托管内存或“删除”托管对象(您无法做到的事情以及垃圾收集器的用途),它用于处理非托管的处理/释放具有可释放项目的资源或其他受管资源,例如SqlConnection
。它肯定不会null
引用,但可能会使其在处置之前无法使用。
如何将其设为null或释放此占用的内存 对象??
如果您想使引用为空,只需dt = null
即可,但不会给您带来任何好处,因为DataTable
实例被grdView.DataSource
引用}。 dt
和grdView.DataSource
都将引用同一个基础DataTable
实例。
我还怀疑这是方法的一部分,其中dt
无论如何都是方法范围。
你不应该过分担心这些事情。我更关心SqlConnection
/ try-finally
之外的using
,你有可能在那里打开连接。
我倾向于在实施Dispose
的项目上调用IDisposable
,我认为这是非常的理由:这是公共合同。调用它是否有效的事实是实施细节,并且可能会立即发生变化。
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;
答案 2 :(得分:2)
尝试使用Clear()函数。这对我来说非常适合处理。
DataTable dt = GetDataSchema();
//populate dt, do whatever...
dt.Clear();