C#优化内存使用:如何释放DataTable声明的内存

时间:2014-11-05 09:57:26

标签: c# memory datatable memory-optimization

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

喜欢在线程的接受答案中提出建议" What is the memory overhead of storing data in a .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 drTest in dtTest.Rows)
{
    dynamic ExpandoItem = new ExpandoObject();
    ExpandoItem.FieldName = drTest["FieldName"].ToString();
    ExpandoList.Add(ExpandoItem);
}
// Second stop point - Total process memory (taskmanager) = 1055 MB
dtTest.Clear();
dtTest.Dispose();
dtTest = 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() will make it remove from memory?

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

我做错了什么? 也许有更好的方法来从DataTable中缩小数据?

1 个答案:

答案 0 :(得分:3)

我终于找到了关于内存使用的这个帖子:.NET EXE memory footprint

接受的答案如下:

  

不应使用TaskManager来测量.NET应用程序的内存占用量。

     

当.NET应用程序启动时,它会向操作系统询问一块内存,然后将其分段   成为托管堆,堆栈和大对象堆。这是总的一大块记忆   TaskManager正在报告,.NET可能会或可能不会完全使用它。曾经是.NET   应用程序被给予一大块内存,直到操作系统询问它才会释放它   只有在OS确定需要更多内存资源时才会发生。

     

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

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

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

long lMemoryMB = GC.GetTotalMemory(true/* true = Collect garbage before measuring */) / 1024 / 1024; // memory in megabytes

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

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