Советы по работе с большими строками в отношении использования памяти - PullRequest
0 голосов
/ 07 января 2010

Как я могу заставить сжатие DataTable и / или List, чтобы я мог эффективно освободить память? В настоящее время я удаляю обработанную строку из набора данных каждую итерацию цикла, но я не уверен, освобождается ли память.

for (int i = m_TotalNumberOfLocalRows - 1; i >= 0; i--)
{
   dr = dt.Rows[i];
   // Do stuff
   dt.Rows.Remove(dr);
}

Если это не уменьшит объем памяти DataTable в памяти, я могу использовать список. Я использую только DataTable в качестве хранилища для DataRows, я мог бы использовать любой механизм сбора или хранения, который бы занимал мало памяти и мог высвобождать память каждые x итераций.

Спасибо.



Edit: После некоторого профилирования памяти после прочтения Что такое хорошие профилировщики .NET? Я обнаружил, что основным потребителем памяти являются строки.

Во время этого процесса мы делаем много пользовательского вывода, и потребление памяти колеблется между 170 МБ и 230 МБ, достигая пика в 300 МБ. Я использую StringBuilder с начальным размером 20971520 для хранения вывода / журнала происходящего, и после обработки одного процента от общего числа записей я устанавливаю свойство Text элемента управления DevExpress MemoEdit в StringBuilder.ToString. (). Я обнаружил, что этот метод быстрее, чем добавление StringBuilder.ToString () к MemoEdit.Text (очевидно, логика w.r.t. StringBuilder отличается между добавлением и настройкой MemoEdit.Text)

Я также обнаружил, что вместо воссоздания StringBuilder (20971520) память становится проще и быстрее выполняется до StringBuilder.Remove(0, StringBuilder.Length)

Есть ли какие-либо советы, которыми вы могли бы поделиться для повышения производительности при работе с большими строками (записанный файл журнала, содержащий журнал, составляет примерно 12,2 МБ для примерно 30 000 записей)?

Примечание. Я изменил название вопроса и теги.
Старое название: Как я могу вызвать сжатие DataTable и / или списка для освобождения памяти?
Старые теги: список данных c # .net memory

Ответы [ 4 ]

4 голосов
/ 07 января 2010

Если у вас нет проблем с памятью, не пытайтесь вручную освободить ее, вызвав сборщик мусора. Время выполнения поможет вам, и 99% времени будет более эффективным, чем вы, пытаясь угадать, когда наступит оптимальное время.

Что вы должны помнить, так это то, что когда вы вызываете GC.Collect (), он работает со всеми уровнями сборки мусора и «убирает» все объекты, которые необходимо освободить. Скорее всего, вы будете тратить процессорное время и т. Д. На то, что не нужно делать в этот момент.

Если вам абсолютно необходимо набрать команду GC.Collect()

http://msdn.microsoft.com/en-us/library/xe0c2357.aspx

http://www.developer.com/net/csharp/article.php/3343191/C-Tip-Forcing-Garbage-Collection-in-NET.htm

1 голос
/ 07 января 2010

Попробуйте форсировать проход сборщика мусора:

GC.Collect();

Если вы хотите убедиться, что все объекты завершены до продолжения выполнения кода, вызовите

GC.WaitForPendingFinalizers();

сразу после GC.Collect ()


РЕДАКТИРОВАТЬ: Как упоминалось в комментариях ниже, широко считается плохой практикой вызывать сборщик мусора напрямую. Тем не менее, это может достичь цели освобождения неиспользованной памяти ваших удаленных строк.

0 голосов
/ 07 января 2010

Есть ли у вас явная необходимость управлять этим напрямую? Сборщик мусора управляет этим для вас.

0 голосов
/ 07 января 2010

Придерживайтесь DataTable и удаляйте ненужные строки, как в вашем примере.

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

...