Quantcast

Memory Leak (Bitmap)Image.FromStream(memory_stream)

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Memory Leak (Bitmap)Image.FromStream(memory_stream)

rgclickit
I believe I discovered a memory leak when creating Bitmaps from the Image.FromStream call. The basic code to reproduce the problem is:

using (System.IO.MemoryStream ms = new System.IO.MemoryStream(_sourceArray)) {
     using (Bitmap srcBitmap = (Bitmap)Image.FromStream(ms)) {
     }
}

where _sourceArray is a byte[] for a bitmap image file. Call the above code in a loop and memory will climb. When calling GC.WaitForPendingFinalizers(), GC.Collect() memory still climbs but slower.

I have attached a solution, WinForms project that demonstrates this issue. BitmapTest.gz
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Memory Leak (Bitmap)Image.FromStream(memory_stream)

rgclickit
I forgot to mention I have reproduced this with Mono 4.6 and 4.8 running on Ubuntu 16.04 LTS.

Thank-you for taking the time to look at this issue.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Memory Leak (Bitmap)Image.FromStream(memory_stream)

rgclickit
When downloading the file to look at the code it will uncompress to BitmapTest. Rename the uncompressed file to BitmapTest.tar.gz in order to extract its contents.

BitmapTest.gz

Thank-you.
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Memory Leak (Bitmap)Image.FromStream(memory_stream)

Robert Jordan
In reply to this post by rgclickit
On 23.03.2017 21:51, rgclickit wrote:
> I believe I discovered a memory leak when creating Bitmaps from the
> Image.FromStream call. The basic code to reproduce the problem is:
>
> using (System.IO.MemoryStream ms = new System.IO.MemoryStream(_sourceArray))
> {
>      using (Bitmap srcBitmap = (Bitmap)Image.FromStream(ms)) {
>      }
> }
>

I cannot reproduce this. The odds are that you're not computing
the memory usage correctly.

See
http://www.mono-project.com/docs/advanced/performance-tips/#understanding-memory-usage

Robert


_______________________________________________
Mono-devel-list mailing list
[hidden email]
http://lists.dot.net/mailman/listinfo/mono-devel-list
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Memory Leak (Bitmap)Image.FromStream(memory_stream)

rgclickit
I am using System Monitor to look at the memory usage. I ran the program I uploaded (see link in previous posts) this morning and it was using over 1.6 GB after a few hours.

If I use Image.FromFile(_file_name) instead of Image.FromStream(ms) the same code works fine, memory usage in System Monitor doesn't change.

Thank-you for looking at this. I appreciate any help.

Ray
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Memory Leak (Bitmap)Image.FromStream(memory_stream)

rgclickit
In reply to this post by Robert Jordan
Here is the code directly from the BitmapTest program:

            while (_runTest)
            {
                try
                {
                    // convert the byte[] array to a Bitmap using Image.FromStream
                    // This will demonstrate a memory leak in Mono 4.6 and 4.8.
                    using (System.IO.MemoryStream ms = new System.IO.MemoryStream(_sourceArray))
                    {
                        if (firstRun)
                        {
                            PaintStatus("First memory stream created OK size: " + ms.Capacity.ToString());
                        }
                        using (Bitmap srcBitmap = (Bitmap)Image.FromStream(ms))
                        {
                            if (firstRun)
                            {
                                PaintStatus("First Bitmap created OK size: " + srcBitmap.Size.ToString());
                                PaintStatus("Going to continue to run until Stopped");
                            }
                            firstRun = false;
                        }
                    }
                    if (_forceGC)
                    {
                        GC.WaitForPendingFinalizers();
                        GC.Collect();
                    }
                }
                catch (Exception ex)
                {
                    PaintStatus("Error " + ex.Message);
                }
            }

The PaintStatus call:
        private void PaintStatus(string StatusMessage)
        {
            try
            {
                if (this.InvokeRequired)
                {
                    this.Invoke(new status_info(PaintStatus), new object[] { StatusMessage });
                    return;
                }
            }
            catch (Exception) { return; }

            try
            {
                string df = DateTime.Now.ToString("dd-MM hh:mm:ss");

                if (lstActivity.Items.Count > 2000)
                {
                    lstActivity.Items.RemoveAt(lstActivity.Items.Count - 1);
                }

                lstActivity.Items.Insert(0, df + " " + StatusMessage);
            }
            catch (Exception) { return; }
        }

When I started running:

Bitmap Test program

After 3 minutes of runtime from System Monitor
After 3 minutes


After 6 minutes of runtime from System Monitor
After 6 minutes

After 10 minutes of runtime from System Monitor
After 10 minutes

The memory keeps increasing and never drops. If I remove the memory stream and use:

 using (Bitmap srcBitmap = (Bitmap)Image.FromFile(_file_name))

the memory usage doesn't change.

Again, thanks for any help you can provide.


Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Memory Leak (Bitmap)Image.FromStream(memory_stream)

Robert Jordan
In reply to this post by Robert Jordan
On 24.03.2017 20:17, Robert Jordan wrote:

> On 23.03.2017 21:51, rgclickit wrote:
>> I believe I discovered a memory leak when creating Bitmaps from the
>> Image.FromStream call. The basic code to reproduce the problem is:
>>
>> using (System.IO.MemoryStream ms = new
>> System.IO.MemoryStream(_sourceArray))
>> {
>>      using (Bitmap srcBitmap = (Bitmap)Image.FromStream(ms)) {
>>      }
>> }
>>
>
> I cannot reproduce this. The odds are that you're not computing
> the memory usage correctly.
>
> See
> http://www.mono-project.com/docs/advanced/performance-tips/#understanding-memory-usage


I was testing with a too large bitmap and hence too few iterations/sec.
With a 1x1 bitmap the leak started to become evident, so it
probably depends on how often Image.FromStream is getting called.

The code behind Image.FromStream is pretty complex because the
underlying unmanaged library (libgdiplus) knows nothing about
managed streams.

Hard to say, where to leak is. It might be an unmanaged one...

You may want to file a bug, ideally with a test case which doesn't
depend on WinForms, like this one:

---
using System;
using System.Drawing;
using System.IO;

class Program
{
        static void Run ()
        {
                using (var stream = File.OpenRead ("test.bmp"))
                        using (Image.FromStream (stream)) {
                 }
        }

         static void Main ()
         {
                 for (int i = 0; i < 100000; i++)
                         Run ();
         }
}
---

Robert


_______________________________________________
Mono-devel-list mailing list
[hidden email]
http://lists.dot.net/mailman/listinfo/mono-devel-list
Reply | Threaded
Open this post in threaded view
|  
Report Content as Inappropriate

Re: Memory Leak (Bitmap)Image.FromStream(memory_stream)

rgclickit
I have filed a bug report here:

https://bugzilla.xamarin.com/show_bug.cgi?id=54149

Thanks again for your help.

Ray
Loading...