最佳实践,在C#优化内存 [英] Best practices to optimize memory in C#

查看:265
本文介绍了最佳实践,在C#优化内存的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

什么是C#来优化内存的最佳实践。



我使用以下方法来优化我的记忆中。




  1. 处置的对象使用后或使其无效。

  2. 使用尝试/最后还是使用块。
  3. 如果需要
  4. 使用GC.Collect的()。

  5. 删除不必要的对象初始化。

  6. 管理图像缓存。

  7. 疥癣BLOB数据,内存流和文件流



即使有内存泄漏



我的应用程序是使用以下的事情:




  1. 处理配置文件,

  2. 使用其他的XML文件。

  3. 使用图像的功能放大,缩小功能,显示不同类型的图像,改变图像的颜色,在XML保存数据。

  4. 保存在SQL服务器数据。


解决方案

您可以使用展鹏蚂蚁内存分析器



CLR探查(免费)(的http://msdn.microsoft.com/en-us/library/ms979205.aspx#scalenethowto13_topic2



<()是不是即便是在某些情况下需要推荐STRONG> GC.Collect的:



请看看下面的代码:

 私人无效WriteStringOnImage()
{

{
的byte [] imgData =的getData(@E:\0000.tif);使用
(System.Drawing.Image对象IMG = System.Drawing.Image.FromStream(新的MemoryStream(imgData)))
{
的for(int i = 1; I< = 1000;我++)
{
位图IMG1 =新位图(新位图(IMG));
的RectangleF rectf =新的RectangleF(800,550,200,200);
图形G = Graphics.FromImage(IMG1);
g.DrawString(i.ToString(0000),新的字体(Thaoma,30),Brushes.Black,rectf);
img1.Save(@E:\Img\+ i.ToString(0000)+。TIF);
g.Flush();
g.Dispose();
img1.Dispose();
GC.Collect的();
}
}
}
赶上(例外){}
}

在上面的例子中我用的 GC.Collect的(),因为如果我不使用 GC.Collect的(),然后它正在内存周围的 1500MB 。但在使用后的 GC.Collect的()如果从未超过比 75MB



即。内存利用率的由20倍下降



但如果GC.Collect的()正被过度使用,有没有趴在很多未使用的对象那么内存GC.Collect的()将放缓你的表现,它是费时。



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



如果您是内存流的byte []或任何其他类型的流,那么你应该使用使用块工作。



有时你也需要清空一些对象的使其空
正如我们所知道的数据,如果我们处理XML数据,那么它需要非常沉重的记忆,所以我们需要自由使用,但是XML下课后内存没有实现IDisposable接口,所以你必须让它空
例如的XmlDocument = NULL;



您也应该牢记关于不必要的对象初始化



例如



而不是

  ClassA的ABC =新ClassA的(); 
ABC = XYZ;

使用



  ClassA的ABC = XYZ; 



尝试使用方法级别的变量,而不是一流水平如果在只有一个方法被使用。



请确保您清除集合对象。



由任何第三方工具,这是守望的内存使用情况在应用程序中使用。有时,第三方工具需要非常高的内存。



使用静态的,只有当它是必须



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



如果任何大的对象在层次班正在处理保持它的手表。



如果任何XML文档进行处理,并已保存在存储器中以供将来使用,这将是在使用后的任何事件,然后释放该存储器和负载XML时的需要触发事件。



避免克隆



如果您正在使用字符串处理工作,就可以检查数据的无限循环。像省略号(...)有时特殊的Unicode字符可以创建问题,并导致了无限循环。



您也可以使用 dotTrace 内存分析器通过Jetbrain。



您还可以看看事件日志作为,这是造成该问题的任何异常。



如果任何位图对象正在建立,并正在做了一些图像处理,然后对非托管资源看看。 A 位图对象采取非托管资源一个巨大的内存,并且可能不会被释放。



正如你所提到的,你还使用SQL服务器然后还要继续 SQL服务器程序和函数并调用他的策略手表。



在SQL Server如果保存任何数据,图像数据类型如果是大于1MB,那么请使用 VARBINARY(MAX)FILESTREAM与属性,但它会与SQL Server 2008或SQL服务器上版本。


What are the best practices to optimize memory in C#.

I am using following technique to optimize my memory.

  1. Dispose an object after use or make it null.
  2. Use try/finally or using block.
  3. Use GC.Collect() if required.
  4. Remove unnecessary object initialization.
  5. Manage Image caching.
  6. Mange BLOB data, Memory stream and file stream

Even if there is memory leakage.

My application is using following things:

  1. Processing configuration files,
  2. Using other XML files.
  3. Using image functions zoom-in, zoom-out, display different type of images, changing color of images, saving data in xml.
  4. Saving data in SQL server.

解决方案

You can use Redgate ANTS Memory profiler.

Or CLR profiler (free) (http://msdn.microsoft.com/en-us/library/ms979205.aspx#scalenethowto13_topic2 )

GC.Collect() is not recommended even if it is required in some cases:

please have a look at below code:

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){}
    }

In the above example I used GC.Collect() because If I do not use GC.Collect() then it is taking memory around 1500mb. But after use of GC.Collect() if is never exceeding than 75mb

i.e. Memory utilization is decreased by 20times.

But if GC.Collect() is being used excessively and there are not much unused objects lying in the memory then GC.Collect() will slowdown your performance and it is time consuming.

You can also use Dispose() if it implements Idisposable.

If you are working with Memory Stream byte[] or any other type of stream then you should use the using blocks.

Sometimes you also need to empty some object by making it null. As we know data if we process XML data then it takes very heavy memory so we need to free the memory after use but XML class doesn't implement Idisposable interface so you have to make it null e.g. xmldocument=null;

You should also keep in mind about unnecessary object initialization.

e.g.

instead of

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

use

ClassA abc=xyz;

Try to use method level variable instead of class level if it is being used in only one method.

Make sure you are clearing collection objects.

Keep watch on the memory usage by any third party tool which is being used in your application. Sometimes third party tools takes very high memory.

Use static only if it is must

use StringBuilder instead of String. Because if string is concatenated then a new memory is allocated so the old memory data is not being used but it is kept in RAM.

If any large object is being processed in hierarchical classes keep watch on it.

If any XML document is processed and has been kept in memory for future use and that will be use after any event then release that memory and load XML when the required event is fired.

Avoid cloning .

If You are working with string manipulation you can check the data for infinite loop. Sometime special Unicode characters like ellipsis(...) can create problem and causes for infinite loop.

You can also use dotTrace a memory profiler by Jetbrain.

You can also look into event log for any exception which is causing the issue.

If any bitmap object is being created and some image processing is being done then have a look on unmanaged Resources. A bitmap object take a huge memory for unmanaged resources and that might not be released.

As you have mentioned that you are also using SQL server then also keep watch on SQL server procedures and functions and their calling strategies.

In SQL Server if you are saving any data as image data type and if it is larger than 1mb then please use varbinary(MAX) with filestream property but it will work with SQL server 2008 or upper versions of SQL server.

这篇关于最佳实践,在C#优化内存的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆