Рекомендации по оптимизации памяти в C# [закрыто]

каковы наилучшие методы оптимизации памяти в C#.

Я использую следующую технику для оптимизации моей памяти.

  1. Dispose объект после использования или сделать его null.
  2. используйте try / finally или using block.
  3. используйте GC.Сбор() при необходимости.
  4. удалить ненужную инициализацию объекта.
  5. управление кэшированием изображений.
  6. данные mange BLOB, поток памяти и поток файлов

даже если происходит утечка памяти.

мое приложение использует следующие вещи:

  1. обработка конфигурационных файлов,
  2. использование других XML-файлов.
  3. использование функций изображения увеличение, уменьшение, отображение различных типов изображений, изменение цвета изображений, сохранение данных в xml.
  4. сохранение данных в SQL server.

4 ответов


можно использовать Redgate муравьи профилировщик памяти (несвободной).

или CLR profiler (бесплатно): https://msdn.microsoft.com/library/ms979205

GC.Collect() не рекомендуется, даже если это требуется в некоторых случаях. Пожалуйста, посмотрите на код ниже:

private void WriteStringOnImage()
{
    try
    {
        byte[] imgData = getData(@"E:00.tif");
        using (System.Drawing.Image img = System.Drawing.Image.FromStream(new MemoryStream(imgData)))
        {
            for (int i = 1; i <= 1000; i++)
            {
                Bitmap img1 = new Bitmap(new Bitmap(img));
                RectangleF rectf = new RectangleF(800, 550, 200, 200);
                Graphics g = Graphics.FromImage(img1);
                g.DrawString(i.ToString("0000"), new Font("Thaoma", 30), Brushes.Black, rectf);
                img1.Save(@"E:\Img\" + i.ToString("0000") + ".tif");
                g.Flush();
                g.Dispose();
                img1.Dispose();
                GC.Collect();
            }
        }
    }
    catch (Exception){}
}

в приведенном выше примере я использовал GC.Collect() потому что если я не использую GC.Collect() тогда это занимает память вокруг 1500 МБ. Но после использования GC.Collect() если никогда не превышает 75 МБ

т. е. использование памяти уменьшилось в 20 раз.

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

вы также можете использовать Dispose() если он реализует IDisposable.

если вы работаете с MemoryStream или любой другой тип потока, тогда вы должны использовать using блоки.

иногда вам также нужно пустой какой-то объект, сделав его null.

как мы знаем, данные если мы обрабатываем данные XML, то это занимает очень тяжелую память, поэтому нам нужно освободить память после использования, но класс XML не реализует интерфейс Idisposable, поэтому вы должны сделать его нулевым (например,xmldocument=null;)

вы также должны иметь в виду о ненужная инициализация объекта.

например, вместо:

ClassA abc=new ClassA();
abc=xyz;

использование:

ClassA abc=xyz;

попробуйте использовать переменную уровня метода вместо уровня класса, если она используется только в одном методе.

убедитесь, что вы очищаете объектов коллекции.

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

использовать static только если это должен.

использовать StringBuilder вместо String. потому что если строка объединена, то выделяется новая память, поэтому старые данные памяти не используются, но хранятся в ОЗУ.

если какой-либо большой объект обрабатывается в иерархических классах, следите за ним.

если какой-либо XML-документ обрабатывается и хранится в памяти для дальнейшего использования, и это будет использоваться после любого события, то отпустите эту память и загрузите XML когда необходимые события.

избежать клонирования.

если вы работаете со Строковой манипуляцией, вы можете проверить данные для бесконечного цикла. Иногда специальные символы Юникода, такие как многоточие(...) может создавать проблемы и причины для бесконечного цикла.

вы также можете использовать dotTrace профилировщик памяти Jetbrain.

вы также можете посмотреть на журнал событий для любого исключения, которое является причина проблемы.

если объект Bitmap создается, и некоторая обработка изображений выполняется, затем посмотрите на неуправляемые ресурсы. А растровый объект занимает огромную память для неуправляемых ресурсов и это может быть не выпущено.

как вы упомянули, что вы также используете SQL server, а затем также следите за процедуры и функции SQL server и их стратегии вызова.

в SQL Сервер если вы сохраняете какие-либо данные как тип данных изображения и если он больше 1 Мб, пожалуйста, используйте varbinary (MAX) с filestream свойство, но оно будет работать с SQL server 2008 или верхними версиями SQL server.


рекомендации по оптимизации памяти в C#,

  1. создать только объекты, по мере необходимости
  2. решите область для каждой переменной и объекта, если они требуются внутри методов, объявите их внутри этих методов, не делайте их private
  3. использовать IDisposable интерфейсы пользовательские объекты и освободить все ресурсы(если таковые имеются), отменить регистрацию всех событий и т. д.
  4. вызов dispose когда объект не требуется для пользовательские объекты
  5. использовать static переменные или экземпляры, если требуется, то тоже подумайте дважды, требуются ли эти объекты в течение всего срока службы программы
  6. не используйте GC.Collect() вручную,(это плохая практика)

многие из них на самом деле не оптимизируют память...

  1. Dispose объект после использования или сделать его null. всегда Dispose() объект, если это IDisposable. Это может избавить вас от проблем с памятью, но не обязательно. (Также используйте Using Если возможно)
  2. используйте try / finally или using block. try/finally - Это похоже на Using для объектов, которые не IDisposable (Я нахожу их грязными, поэтому я предпочитаю этой решение.)
  3. используйте GC.Сбор() при необходимости. Я бы никогда не смог рекомендовать GC.Collect(). Обычно GC будет лучше знать, когда собирать что-то, чем вы будете.
  4. удалить ненужную инициализацию объекта. это может определенно помочь. Если ваш код идет вокруг создания объектов, которые не нужны... тогда это может занять немного места. Это может быть своего рода allievated / masked с ленивый Инициализация.
  5. управление кэшированием изображений. это очень расплывчато... Но да... его важно управлять, сколько изображений вы сохранили в памяти. Не всегда желательно хранить образы в памяти... Он может открыть дверь для подкачки других процессов в вашем коде, которые являются более важными.
  6. управление данными BLOB, потоком памяти и потоком файлов Я думаю, что это похоже на #5.

..or make it null не имеет того же эффекта, что и Dispose()! Будьте осторожны. Вы должны только распоряжаться своим объектом. Значение null не требуется. И установите null не освобождает любые ресурсы.

3.Используйте GC.Сбор() при необходимости.

обычно это не требуется, потому что GC имеет свой собственный жизненный цикл, когда собирать.. Начиная с .NET 4.5 вы можете компактировать LOH, если считаете, что существует фрагментация:

GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
GC.Collect();