Рекомендации по оптимизации памяти в C# [закрыто]
каковы наилучшие методы оптимизации памяти в C#.
Я использую следующую технику для оптимизации моей памяти.
- Dispose объект после использования или сделать его null.
- используйте try / finally или using block.
- используйте GC.Сбор() при необходимости.
- удалить ненужную инициализацию объекта.
- управление кэшированием изображений.
- данные mange BLOB, поток памяти и поток файлов
даже если происходит утечка памяти.
мое приложение использует следующие вещи:
- обработка конфигурационных файлов,
- использование других XML-файлов.
- использование функций изображения увеличение, уменьшение, отображение различных типов изображений, изменение цвета изображений, сохранение данных в xml.
- сохранение данных в 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#,
- создать только объекты, по мере необходимости
- решите область для каждой переменной и объекта, если они требуются внутри методов, объявите их внутри этих методов, не делайте их
private
- использовать
IDisposable
интерфейсы пользовательские объекты и освободить все ресурсы(если таковые имеются), отменить регистрацию всех событий и т. д. - вызов
dispose
когда объект не требуется для пользовательские объекты - использовать
static
переменные или экземпляры, если требуется, то тоже подумайте дважды, требуются ли эти объекты в течение всего срока службы программы - не используйте
GC.Collect()
вручную,(это плохая практика)
многие из них на самом деле не оптимизируют память...
-
Dispose объект после использования или сделать его null. всегда
Dispose()
объект, если этоIDisposable
. Это может избавить вас от проблем с памятью, но не обязательно. (Также используйтеUsing
Если возможно) -
используйте try / finally или using block.
try/finally
- Это похоже наUsing
для объектов, которые неIDisposable
(Я нахожу их грязными, поэтому я предпочитаю этой решение.) -
используйте GC.Сбор() при необходимости. Я бы никогда не смог рекомендовать
GC.Collect()
. ОбычноGC
будет лучше знать, когда собирать что-то, чем вы будете. - удалить ненужную инициализацию объекта. это может определенно помочь. Если ваш код идет вокруг создания объектов, которые не нужны... тогда это может занять немного места. Это может быть своего рода allievated / masked с ленивый Инициализация.
- управление кэшированием изображений. это очень расплывчато... Но да... его важно управлять, сколько изображений вы сохранили в памяти. Не всегда желательно хранить образы в памяти... Он может открыть дверь для подкачки других процессов в вашем коде, которые являются более важными.
- управление данными BLOB, потоком памяти и потоком файлов Я думаю, что это похоже на #5.
..or make it null
не имеет того же эффекта, что и Dispose()
!
Будьте осторожны. Вы должны только распоряжаться своим объектом. Значение null
не требуется.
И установите null
не освобождает любые ресурсы.
3.Используйте GC.Сбор() при необходимости.
обычно это не требуется, потому что GC имеет свой собственный жизненный цикл, когда собирать.. Начиная с .NET 4.5 вы можете компактировать LOH, если считаете, что существует фрагментация:
GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
GC.Collect();