Reputation: 1068
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?
Upvotes: 2
Views: 188
Reputation: 51330
From the docs of GetHbitmap
:
You are responsible for calling the GDI
DeleteObject
method 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
FromHbitmap
method makes a copy of the GDI bitmap; so you can release the incoming GDI bitmap using the GDIDeleteObject
method 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.
Upvotes: 9