在C#中优化内存的最佳做法是什么?
我正在使用以下技术来优化我的记忆。
即使存在内存泄漏。
我的应用程序正在使用以下内容:
答案 0 :(得分:10)
您可以使用 Redgate ANTS内存分析器(非免费)。
或 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){}
}
在上面的示例中,我使用了GC.Collect()
,因为如果我不使用GC.Collect()
,则会占用 1500mb 周围的内存。但使用GC.Collect()
后如果永远不会超过 75mb
即。内存利用率减少了20倍。
但如果过度使用GC.Collect()
并且内存中没有多少未使用的对象,那么GC.Collect()
会降低您的性能并且耗时。
如果Dispose()
实施IDisposable
,您也可以使用MemoryStream
。
如果您正在使用using
或任何其他类型的流,那么您应该使用null
块。
有时您还需要通过将某个对象设为xmldocument=null;
来清空它。
如果我们知道数据,如果我们处理XML数据然后它需要非常大的内存,所以我们需要在使用后释放内存但是XML类没有实现Idisposable接口所以你必须使它为null(例如ClassA abc=new ClassA();
abc=xyz;
)
您还应该记住不必要的对象初始化。
e.g。而不是:
ClassA abc=xyz;
使用:
static
如果仅在一个方法中使用方法级变量而不是类级别,请尝试使用它。
确保清除收集对象。
请关注应用程序中使用的任何第三方工具的内存使用情况。有时第三方工具会占用很高的内存。
仅在必须时才使用StringBuilder
。
使用String
代替{{1}}。因为如果字符串连接在一起,则会分配一个新内存,因此旧内存数据不会被使用但会保留在RAM中
如果在分层类中处理任何大对象,请密切关注它。
如果处理了任何XML文档并将其保存在内存中以供将来使用,并且将在任何事件之后使用,那么在触发所需事件时释放该内存并加载XML。
避免克隆。
如果您正在使用字符串操作,则可以检查数据是否为无限循环。有时像Unicode(...)这样的特殊Unicode字符会产生问题并导致无限循环。
你也可以使用Jetbrain的 dotTrace 内存分析器。
您还可以查看事件日志,查看导致此问题的任何异常。
如果正在创建任何位图对象并且正在进行一些图像处理,那么请查看非托管资源。 位图对象为非托管资源占用大量内存,可能无法释放。
正如您所提到的,您也在使用SQL服务器,那么还要关注 SQL服务器程序和功能及其调用策略。
在SQL Server中如果要将任何数据保存为图像数据类型且大于1mb,请使用 varbinary(MAX)和filestream 属性,但它适用于SQL Server 2008或更高版本SQL服务器的版本。
答案 1 :(得分:2)
在C#中优化内存的最佳做法,
private
IDisposable
接口并释放所有资源(如果有),取消注册所有事件等dispose
static
个变量或实例,然后再考虑在整个程序生命周期内是否需要这些对象GC.Collect()
,(这是不好的做法)答案 2 :(得分:2)
其中许多并没有真正优化记忆......
Dispose()
,则始终IDisposable
。这可以节省你的记忆问题,但不一定。 (另外,如果可能,请使用Using
)try/finally
- 对于非Using
的对象,这与IDisposable
类似(我发现它们是GC.Collect()
凌乱,所以我更喜欢this解决方案。)GC
。通常{{1}}会更好地知道什么时候收集东西比你想要的更好。 答案 3 :(得分:0)
..or make it null
与Dispose()
的效果不同!
小心点。你应该只处理你的对象。不需要设置为null
。
并设置为null
不释放任何资源。
3.如果需要,请使用GC.Collect()。
通常这不是必需的,因为GC有自己的生命周期何时收集.. 从.NET 4.5开始,如果您认为存在碎片,则可以压缩LOH:
GCSettings.LargeObjectHeapCompactionMode = GCLargeObjectHeapCompactionMode.CompactOnce;
GC.Collect();