在C#中优化内存的最佳实践

在C#中优化内存的最佳实践是什么?

我正在使用以下技术来优化我的记忆力。

  1. 使用后处理对象或使其为空。
  2. 使用try / finally或使用块。
  3. 如果需要,请使用GC.Collect()。
  4. 删除不必要的对象初始
  5. 管理图像缓存。
  6. Mange BLOB数据,内存流和文件流

即使有内存泄漏。

我的应用程序使用以下内容:

  1. 处理配置文件,
  2. 使用其他XML文件。
  3. 使用图像function放大,缩小,显示不同类型的图像,更改图像颜色,以xml格式保存数据。
  4. 在SQL Server中保存数据。

您可以使用Redgate ANTS Memory Profiler (非免费)。

CLR分析器 (免费): https : //msdn.microsoft.com/library/ms979205

即使在某些情况下需要GC.Collect() ,也不建议使用GC.Collect() 。 请看下面的代码:

 private void WriteStringOnImage() { try { byte[] imgData = getData(@"E:\0000.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()那么它的内存大约为1500mb 。 但使用GC.Collect()如果永远不超过75mb

即内存利用率降低20倍

但是如果过度使用GC.Collect()并且内存中没有太多未使用的对象,则GC.Collect()会降低性能并且耗时。

如果它实现了IDisposable您也可以使用Dispose()

如果您正在使用MemoryStream或任何其他类型的流,那么您应该使用using块。

有时您还需要通过使其清空某个对象

因为我们知道数据如果我们处理XML数据然后它需要非常大的内存所以我们需要在使用后释放内存但XML类不实现Idisposable接口所以你必须使它为null(例如xmldocument=null;

您还应该记住不必要的对象初始化

例如,而不是:

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

使用:

 ClassA abc=xyz; 

如果仅在一个方法中使用方法级别变量而不是类级别,请尝试使用它。

确保清除收集对象。

通过应用程序中使用的任何第三方工具监视内存使用情况。 有时第三方工具占用非常高的内存。

仅在必须时使用static

使用StringBuilder而不是String 因为如果连接字符串然后分配新的内存,那么旧的内存数据不会被使用,但它会保存在RAM中。

如果在分层类中处理任何大对象,请密切关注它。

如果处理了任何XML文档并将其保留在内存中以供将来使用,并且将在任何事件之后使用,那么在触发所需事件时释放该内存并加载XML。

避免克隆。

如果您正在使用字符串操作,则可以检查数据是否为无限循环。 有时像Unicode(...)这样的特殊Unicode字符可能会产生问题并导致无限循环。

你也可以使用dotTrace作为Jetbrain的内存分析器。

您还可以查看事件日志中是否存在导致问题的任何exception。

如果正在创建任何位图对象并且正在进行一些图像处理,那么请查看非托管资源。 位图对象为非托管资源占用大量内存,并且可能无法释放。

正如您所提到的,您还使用SQL服务器,然后还要关注SQL服务器过程和函数及其调用策略。

在SQL Server中,如果要将任何数据保存为图像数据类型,并且如果它大于1mb,那么请使用varbinary(MAX)和filestream属性,但它可以与SQL Server 2008或SQL Server的高级版本一起使用。

在C#中优化内存的最佳实践,

  1. 在需要时仅创建对象
  2. 确定每个变量和对象的范围,如果在方法中需要它们,则在这些方法中声明它们,不要将它们private
  3. 使用自定义对象上的IDisposable接口并释放所有资源(如果有),取消注册所有事件等
  4. 当自定义对象不再需要对象时调用dispose
  5. 如果需要,请使用最少的static变量或实例,然后再考虑在程序的整个生命周期中是否需要这些对象
  6. 不要手动使用GC.Collect() (这是不好的做法)

其中许多并没有真正优化内存……

  1. 使用后处理对象或使其为空。 如果对象是IDisposable始终Dispose() 。 这可以节省你的记忆问题,但不一定。 (另外,如果可能,请使用)
  2. 使用try / finally或使用块。 try/finally – 这类似于UsingIDisposable对象(我觉得它们很乱,所以我更喜欢这个解决方案。)
  3. 如果需要,请使用GC.Collect()。 我真的不能推荐GC.Collect() 。 通常情况下, GC会更好地知道何时收集的东西比你想要的更多。
  4. 删除不必要的对象初始 这个可以肯定有帮助。 如果您的代码正在创建不需要的对象……那么这可能会浪费一些空间。 这可以通过延迟初始化进行分类/屏蔽。
  5. 管理图像缓存。 这非常模糊……但是是……管理你在内存中存储的图像数量非常重要。 将图像保存在内存中可能并不总是令人满意的……它可以为您的代码中更重要的其他进程分页打开大门。
  6. 管理BLOB数据,内存流和文件流我认为这类似于#5。

..or make it nullDispose()没有相同的效果! 小心点。 你应该只处理你的对象。 不需要设置为null 。 并设置为null不释放任何资源。

3.如果需要,使用GC.Collect()。

通常这不是必需的,因为GC有自己的生命周期何时收集..自.NET 4.5以来你可以压缩LOH,如果你认为存在碎片:

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