Как работать с большими списками во время экспорта CSV в .Net Core - PullRequest
0 голосов
/ 01 апреля 2019

У меня есть блок кода, который экспортирует набор записей (более 200 тыс. Записей) в CSV. Большой кусок памяти выделяется во время записи CSV и по какой-то причине он не освобождается сборщиком мусора после возврата файла CSV.

Я пытался использовать GC.Collect (), но я знаю, что он просто не будет работать для больших объектов кучи. GC.WaitForPendingFinalizers () сразу после GC.Collect () также не освобождает всю память, выделенную во время этой операции.

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).

1 Ответ

0 голосов
/ 02 апреля 2019

вернуть новый SpreadsheetFile { FileBytes = memoryStream.ToArray () ...

memoryStream.ToArray сохраняет все данные в array в памяти, и ссылка на них хранится в свойстве FileBytes SpreadsheetFile, поэтому данные не освобождаются GC. Используйте профилировщик памяти, чтобы увидеть, что хранит экземпляр SpreadsheetFile в памяти, если вы считаете, что его не следует хранить.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...