繁体   English   中英

C#优化内存使用:如何释放DataTable要求的内存

[英]C# optimize memory usage: How to free memory claimed by DataTable

目前,我正在优化大型批处理程序的内存使用情况。 最多的内存由不同的数据表使用。 例如,我的DataTable dataTable使用大约260MB。

就像线程接受的答案中的建议“ 在.NET DataTable中存储数据的内存开销是多少? ”,我正在尝试将相关数据移出DataTable。 这是我的代码:

GC.Collect(); // force the garbage collector to free memory
// First stop point - Total process memory (taskmanager) = 900 MB
List<ExpandoObject> expandoList = new List<ExpandoObject>();
foreach (DataRow dataRow in dataTable.Rows)
{
    dynamic expandoItem = new ExpandoObject();
    expandoItem.FieldName = dataRow["FieldName"].ToString();
    expandoList.Add(expandoItem);
}
// Second stop point - Total process memory (taskmanager) = 1055 MB
dataTable.Clear();
dataTable.Dispose();
dataTable = null;
GC.Collect(); // force the garbage collector to free memory
// Third stop point - Total process memory (taskmanager) = 1081 MB (wtf? even more!)

我正在使用Clear,Dispose并将其设置为null,因为在以下线程中建议这样做Datatable.Dispose()会将其从内存中删除吗?

请参阅停止点注释以查看该点的内存使用情况。 我也尝试using (DataTable dataTable = ...)但是结果是相同的。

我究竟做错了什么? 也许有更好的方法来减少DataTable中的数据?

我终于找到了有关内存使用的线程: .NET EXE内存占用量

接受的答案如下:

TaskManager不应用于衡量.NET应用程序的内存占用。

当.NET应用程序启动时,它会请求操作系统提供一块内存,然后将其分段以成为托管堆,堆栈和大对象堆。 TaskManager报告的就是这块内存,.NET可能会完全使用它,也可能不会完全使用它。 一旦为.NET应用程序分配了一块内存,它就不会释放它,除非得到操作系统的要求,这只有在操作系统确定需要更多的内存资源时才会发生。

如果要测量内存分配,则需要查看各种性能>监视器(PerfMon)计数器。

简而言之:任务管理器显示保留的内存而不是实际使用的内存。 这意味着将DataTable设置为null可以正常工作。

可以使用GarbageCollector通过以下代码获取实际使用的内存:

long memoryInMB = GC.GetTotalMemory(forceFullCollection: true) / 1024 / 1024;

我用我的代码尝试了此操作,删除了数据表,使已使用的总内存减少了28MB。 从DataTable提取数据到另一个容器的努力并不值得:-/

我希望这可以帮助其他有相同问题的人。

有关GC,处置和完成的更多信息,请务必参考此答案

暂无
暂无

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

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