【问题标题】:C# optimize memory usage: How to free memory claimed by DataTableC# 优化内存使用:如何释放 DataTable 声明的内存
【发布时间】:2015-01-01 11:09:02
【问题描述】:

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

我正在使用 Clear、Dispose 并设置为 null,因为它在以下线程中被建议:Datatable.Dispose() will make it remove from memory?

查看停止点 cmets 以查看该点的内存使用情况。我也试过using (DataTable dataTable = ...),但结果是一样的。

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

【问题讨论】:

  • 运行内存分析器并查看您的数据表(或其他任何大型数据表)是否仍在被引用。
  • dtTest 从何而来?它是方法调用的参数吗?如果是这样,它仍然会被调用方法引用,因此它不符合垃圾回收的条件。
  • 它来自同一个函数。问题是我使用任务管理器检查内存大小。我不知道.NET中有保留内存。

标签: c# memory datatable memory-optimization


【解决方案1】:

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

接受的答案如下:

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

当 .NET 应用程序启动时,它会向操作系统请求一块内存,然后将其分段 成为托管堆、栈和大对象堆。就是这块内存 TaskManager 正在报告,.NET 可能会也可能不会完全使用它。一旦一个 .NET 应用程序被分配了一块内存,在操作系统询问之前它不会释放它,这 只会发生在操作系统确定需要更多内存资源的情况下。

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

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

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

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

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

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

有关 GC、Dispose 和 Finalize 的更多信息,您绝对应该查看this answer

【讨论】:

    猜你喜欢
    • 2015-08-19
    • 2020-09-10
    • 1970-01-01
    • 2014-05-05
    • 2012-06-02
    • 2015-09-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多