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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C#优化内存使用:如何释放DataTable要求的内存相关的知识,希望对你有一定的参考价值。

目前,我正在优化大型批处理程序的内存使用。最多的内存由不同的数据表使用。例如,我的DataTable dataTable使用大约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 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!)

我正在使用清除,处置并将其设置为null,因为在以下线程中建议使用:Datatable.Dispose() will make it remove from memory?

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

我在做什么错?也许有更好的方法来减少来自DataTable的数据?

答案

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

接受的答案如下:

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

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

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

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

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

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

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

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

以上是关于C#优化内存使用:如何释放DataTable要求的内存的主要内容,如果未能解决你的问题,请参考以下文章

windowsXP下怎样释放电脑内存

JAVA性能优化总结

C# DataTable.Rows.Clear() 不清除行[重复]

Android 性能优化之内存泄漏检测以及内存优化(上)

Android 内存优化,如何避免OOM

Android 性能优化之内存泄漏检测以及内存优化(上)