TextWriter/StreamWriter высокое использование памяти

У меня есть консольное приложение, которое читает большой текстовый файл с 40k+ строками, каждая строка - это ключ, который я использую при поиске, результаты которого записываются в выходной файл. Проблема в том, что я оставляю это консольное приложение работающим некоторое время, пока оно внезапно не закрывается, и я понимаю, что использование памяти процессами было очень высоким, оно было на уровне 1,6 ГБ, когда я в последний раз видел его сбой.

Я посмотрел вокруг и не нашел много ответов, я пытался использовать gcAllowVeryLargeObjects, но похоже, что я просто уклоняюсь от проблемы.

Ниже приведен фрагмент из моего main(), где я записываю в файл. Я не могу понять, почему использование памяти становится таким высоким. Я очищаю писателя после каждой записи (это может быть потому, что я держу файл открытым в течение такого длительного периода времени?).

TextWriter writer = new StreamWriter("output.csv", false));
foreach (var item in list)
 {
  Console.WriteLine("{0}/{1}", count, numofitem);
  var result = TableServiceContext.Read(p.id);
  if (result != null)
  {

   writer.WriteLine(String.Join(",", result.id,
   result.code,
   result.hash));

  }
  count++;
  writer.Flush();
 }
 writer.Close();

Изменить: у меня есть 32 ГБ оперативной памяти на моем компьютере, поэтому я уверен, что он не хватает памяти, потому что мне не хватает оперативной памяти.

Edit2: изменил имя хранилища, поскольку это вводило в заблуждение.

2 ответа

Если средняя длина строки составляет 1 КБ, то 40 КБ строк - это 40 МБ, и это ничего. Поэтому я уверен, что проблема в вашем классе репозитория. Если это EF-репозиторий, попробуйте воссоздать DbContext для каждой строки.

Если вы хотите настроить свою программу, то вы можете использовать следующий метод: попробуйте поставить метки времени на вывод консоли, вы можете использовать класс секундомера и пытаться воссоздавать свой репозиторий каждые 10, 100 или N строк. Затем, глядя на временные метки, вы можете найти оптимальный N для использования.

var timer = Stopwatch.StartNew();
...
Console.WriteLine(timer.ElapsedMilliseconds);

Глядя на код, я думаю, что проблема не в Streamwriter, а в некоторой утечке памяти в вашем хранилище. Предложения для проверки:

  • замените репозиторий каким-нибудь фиктивным, например, классом dummy_repository с тремя свойствами: id, value, hash.
  • аналогичным образом создайте длинный "список", например, 40 тыс. небольших записей.
  • запустите вашу программу и посмотрите, будет ли она по-прежнему потреблять память (я уверен, что она не будет)
  • затем шаг за шагом добавьте обратно свои оригинальные детали. Посмотрите, какой шаг вызывает утечку памяти.
Другие вопросы по тегам