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.