Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Best practices to optimize memory in C# [closed]

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.
like image 866
MK Sharma Avatar asked Jan 10 '14 14:01

MK Sharma


People also ask

What is memory optimization in C?

Memory optimization is a range of techniques related to improving computer memory, such as identifying memory leaks and corruption, to optimize memory usage and increase performance and application usability.


1 Answers

You can use Redgate ANTS Memory profiler (non-free).

Or CLR profiler (free): https://msdn.microsoft.com/library/ms979205

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 20 times.

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

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

If you are working with MemoryStream 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.

like image 185
Banketeshvar Narayan Avatar answered Oct 14 '22 13:10

Banketeshvar Narayan