Akash Kava
Akash Kava

Reputation: 39916

Memory Leak in WPF Image Resizing

I have following image resize and save code.

This code is executed in different thread in ASP.NET MVC Project. As

using (FileStream fs = new FileStream(file.File.FullName, 
                FileMode.Open, FileAccess.Read, FileShare.Read))
{
    BitmapDecoder decoder = BitmapDecoder.Create(fs, 
          BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.None);

    var img = decoder.Frames[0];
    img.Freeze();
    double width = Size;
    double height = Size;

    if (img.PixelWidth > img.PixelHeight)
    {
        height = (int)(((double)img.PixelHeight / (double)img.PixelWidth) 
           * (double)width);
    }
    else
    {
        width = (int)(((double)img.PixelWidth / (double)img.PixelHeight) 
           * (double)height);
    }

    var target = new TransformedBitmap(img,
        new ScaleTransform(width / (double)img.PixelWidth, height 
                / (double)img.PixelHeight, 0, 0));

    RenderOptions.SetBitmapScalingMode(target, BitmapScalingMode.HighQuality);

    var t = BitmapFrame.Create(target);
    RenderOptions.SetBitmapScalingMode(t, BitmapScalingMode.HighQuality);

    target.Freeze();
    t.Freeze();
    JpegBitmapEncoder enc = new JpegBitmapEncoder();
    enc.Frames.Add(t);
    enc.QualityLevel = 90;
    using (FileStream fsout = saved.File.OpenWrite())
    {
        enc.Save(fsout);
    }
}

I have used using around every IDisposable object, WPF objects do not implement IDisposable so I cant dispose them manually.

I read somewhere that calling Freeze will prevent memory leaks, but even after this, no improvement. Memory usage of this process keep on increasing.

What I need is, when an Image is uploaded, it has to be resized in 4 different resolutions, 150x150, 350x350, 700x700 and 1000x1000 , each of these resolutions are invoked parallely using Parallel.ForEach method.

My rest of website is just plain simple Database access using Entity Framework, which I doubt can cause any memory leak upto 3GB of memory usage.

Upvotes: 2

Views: 643

Answers (1)

jschroedl
jschroedl

Reputation: 4986

I tried putting this in a loop in a stand-alone test program and followed the function with an explicit GC.Collect(). On .NET 4.5 at least, this shows that this code does not leak -- the memory stays steady after many many calls.

I think you'll need to look elsewhere in your code. You should try to profile it with Analyze > Launch Performance Wizard... and select .NET Memory Allocations and see what's using the memory.

For fun, I also tried .NET 3.5 and didn't experience a leak their either.

Upvotes: 1

Related Questions