【问题标题】:How to deal with large Lists during a CSV Export in .Net Core如何在 .Net Core 中的 CSV 导出期间处理大型列表
【发布时间】:2019-04-01 18:23:25
【问题描述】:

我有一段代码可以将一组记录(超过 20 万条记录)导出到 CSV。在 CSV 写入过程中分配了一个大内存块,并且由于某种原因,在返回 CSV 文件后它没有被垃圾收集器释放。

我尝试过使用 GC.Collect(),但我知道它不适用于大型堆对象。 GC.Collect() 之后的 GC.WaitForPendingFinalizers() 也不会释放在此操作期间分配的所有内存。

using (var memoryStream = new MemoryStream())
{
  using (var streamWriter = new StreamWriter(memoryStream))
  using (var csvWriter = new CsvWriter(streamWriter))
  {
    csvWriter.Configuration.Delimiter =_configuration["Csv:Delimiter"];
    csvWriter.Configuration.CultureInfo = new CultureInfo(_configuration["Csv:Culture"]);

    if (!noClassMap)
    {
      csvWriter.Configuration.RegisterClassMap<U>();
    }

    //When writing 200,000 records, 500MB get allocated here, and never 
    freed. Details is an IQueryable that returns a 200,000 records 
    result. 
    csvWriter.WriteRecords(details);
  }

  return new SpreadsheetFile { FileBytes = memoryStream.ToArray(), FileName = fileName + DateTime.Now.ToShortDateString() + ".csv" };
}

我知道在写入内存流的过程中,所有的对象列表都会被分配到内存中。 但是,这不应该在 Web API 返回实际 CSV 后释放吗?我不确定这是否是预期的,或者这是某种内存泄漏(运行 .NET Core 2.2.3)。

【问题讨论】:

  • 分析您的代码。

标签: c# .net asp.net-core memory


【解决方案1】:

return new SpreadsheetFile { FileBytes = memoryStream.ToArray()...

memoryStream.ToArray 将所有数据存储到内存中的array 中,并且对它的引用由SpreadsheetFileFileBytes 属性保存,这就是GC 不释放数据的原因。 如果您认为不应该保留 SpreadsheetFile 的实例,请使用内存分析器查看是什么保留在内存中。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-12-29
    • 2012-05-30
    • 1970-01-01
    • 2015-10-10
    • 2020-10-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多