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

MK *_*rma 9 c# memory-leaks

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

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

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

即使有内存泄漏.

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

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

Ban*_*yan 12

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

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

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){}
}
Run Code Online (Sandbox Code Playgroud)

在我上面使用的例子中,GC.Collect()因为如果我不使用GC.Collect()那么它的内存大约为1500mb.但使用后GC.Collect()if永远不会超过75mb

即内存利用率降低20倍.

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

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

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

有时你还需要通过制作它null清空一些物体.

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

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

例如,而不是:

ClassA abc=new ClassA();
abc=xyz;
Run Code Online (Sandbox Code Playgroud)

使用:

ClassA abc=xyz;
Run Code Online (Sandbox Code Playgroud)

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

确保清除收集对象.

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

static仅在必须使用时使用.

StringBuilder而不是String.因为如果字符串连接在一起,则会分配一个新内存,因此旧的内存数据不会被使用,但会保存在RAM中.

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

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

避免克隆.

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

您也可以使用JetTin的dotTrace内存分析器.

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

如果正在创建任何位图对象并且正在进行一些图像处理,那么请查看非托管资源.一个位图对象采取非托管资源的一大内存,并可能不会被释放.

正如您所提到的那样,您也在使用SQL服务器,那么还要密切关注SQL服务器的过程和函数及其调用策略.

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


poy*_*poy 5

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

  1. 使用后丢弃对象或使其无效。Dispose()如果是,则 始终是一个对象IDisposable。这可以避免你的内存问题,但不一定。(另外,Using如果可能的话使用)
  2. 使用 try/finally 或 using block。 - 这与不存在的对象try/finally类似(我发现它们很混乱,所以我更喜欢这个解决方案。)UsingIDisposable
  3. 如果需要,请使用 GC.Collect()。我真的无法推荐GC.Collect()。通常,他们GC会比您更好地知道何时收集东西。
  4. 删除不必要的对象初始化。 这绝对可以提供帮助。如果您的代码正在创建不需要的对象......那么这可能会浪费一些空间。这可以通过延迟初始化来缓解/掩盖。
  5. 管理图像缓存。 这是非常模糊的......但是是的......管理内存中存储的图像数量很重要。将图像保留在内存中可能并不总是可取的......它可以为代码中更关键的其他进程打开分页之门。
  6. 管理 BLOB 数据、内存流和文件流 我认为这与#5 类似。