在C#中优化内存的最佳实践是什么?
我正在使用以下技术来优化我的记忆力.
即使有内存泄漏.
我的应用程序使用以下内容:
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的高级版本一起使用.
其中许多并没有真正优化内存......
Dispose()如果是,则 始终是一个对象IDisposable。这可以避免你的内存问题,但不一定。(另外,Using如果可能的话使用)try/finally类似(我发现它们很混乱,所以我更喜欢这个解决方案。)UsingIDisposableGC.Collect()。通常,他们GC会比您更好地知道何时收集东西。