In the Windows Task Manager I discovered that memory usage of my program is increases over time while it's running. The memory leak is caused by the code below. The code is a loop iterating over a list of images and resizes them according to code example in MSDN. All resources seem to be managed and are freed with .Dispose().
foreach ( string file in files )
{
image = Image.FromFile( file );
Rectangle cropRect = new Rectangle( 0, 0, 1000, 1000 );
Bitmap src = ( Bitmap ) image;
Bitmap target = new Bitmap( cropRect.Width, cropRect.Height );
using ( Graphics g = Graphics.FromImage( target ) )
{
g.DrawImage( src, new Rectangle( 0, 0, target.Width, target.Height ),
cropRect,
GraphicsUnit.Pixel );
}
image.Dispose();
image = Image.FromHbitmap( target.GetHbitmap() );
src.Dispose();
target.Dispose();
image.Dispose();
}
Could someone advise please what can be the cause of the memory leak in this code?
From the docs of GetHbitmap:
You are responsible for calling the GDI
DeleteObjectmethod to free the memory used by the GDI bitmap object. For more information about GDI bitmaps, see Bitmaps in the Windows GDI documentation.
Then, from the docs of FromHbitmap:
The
FromHbitmapmethod makes a copy of the GDI bitmap; so you can release the incoming GDI bitmap using the GDIDeleteObjectmethod immediately after creating the new Image.
Seems pretty clear... You need to call DeleteObject:
[DllImport("gdi32.dll")]
private static extern bool DeleteObject(IntPtr hObject);
As SJoshi points out, you should use using blocks to ensure Dispose is called in case of exception. The DeleteObject call should be inside a finally block to get the same effect.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With