Vitalis Hommel
Vitalis Hommel

Reputation: 1040

Finding the memory leak in ResizeImage

I am getting a memory leak - oom exception - at using (var ergebnis = ResizeImage(Bitmap.FromFile(f), 1, 1))

Where is the memory leak, where is a dispose missing?

SQLiteConnection.CreateFile("datenbank.sqlite");
m_dbConnection =
new SQLiteConnection("Data Source=datenbank.sqlite;Version=3;");
m_dbConnection.Open();
string sql = "CREATE TABLE verbindungen (farbeR NUMERIC, farbeG NUMERIC, farbeB NUMERIC, Dateiname TEXT)";
SQLiteCommand command = new SQLiteCommand(sql, m_dbConnection);
command.ExecuteNonQuery();
int k = 0;
foreach (var f in files)
{
    k++;
    this.Invoke((MethodInvoker)delegate
    {
        this.Text = "Datei "+k+ " von "+files.Length+", Fehler: " + fehler;
    });

    using (FileStream file = new FileStream(f, FileMode.Open, FileAccess.Read))
    {
        using (var ergebnis = ResizeImage(Bitmap.FromFile(f), 1, 1))
        {
            Color ds = ergebnis.GetPixel(0, 0);
            //
            using (var command2 = new SQLiteCommand())
            {
                sql = "INSERT INTO verbindungen VALUES(" + ds.R + ", " + ds.G + ", " + ds.B + ", '" + f + "')";
                command2.CommandText = sql;
                command2.Connection = m_dbConnection;
                command2.ExecuteNonQuery();
            }

        }
    }

    try
    {

    }
    catch (Exception)
    {
        this.Invoke((MethodInvoker)delegate
        {
            fehler++;
        });
        //
    }
    //MessageBox.Show(f + ": " + abstand(ds,vergleichsfarbe));
}

with

public static Bitmap ResizeImage(Image image, int width, int height)
{
    var destRect = new Rectangle(0, 0, width, height);
    var destImage = new Bitmap(width, height);

    destImage.SetResolution(image.HorizontalResolution, image.VerticalResolution);

    using (var graphics = Graphics.FromImage(destImage))
    {
        graphics.CompositingMode = CompositingMode.SourceCopy;
        graphics.CompositingQuality = CompositingQuality.HighSpeed;
        graphics.InterpolationMode = InterpolationMode.Low;
        graphics.SmoothingMode = SmoothingMode.None;
        graphics.PixelOffsetMode = PixelOffsetMode.None;

        using (var wrapMode = new ImageAttributes())
        {
            wrapMode.SetWrapMode(WrapMode.TileFlipXY);
            graphics.DrawImage(image, destRect, 0, 0, image.Width, image.Height, GraphicsUnit.Pixel, wrapMode);
        }
    }

    return destImage;
}

Upvotes: 1

Views: 57

Answers (1)

Kirk Woll
Kirk Woll

Reputation: 77556

This line:

using (var ergebnis = ResizeImage(Bitmap.FromFile(f), 1, 1))

Creates a new bitmap (a disposable resource) on Bitmap.FromFile. That argument is never disposed of in ResizeImage. Most idiomatic is to dispose at the callsite, so you would probably best be off refactoring the code to:

using (var image = Bitmap.FromFile(f))
using (var ergebnis = ResizeImage(image, 1, 1))

That way, both will get disposed. From your comments, it seems you are confusing your original code, which was disposing of the return value of ResizeImage with the need to also dispose of the argument you pass into your method.

Upvotes: 1

Related Questions