Forums

Welcome Guest Search | Active Topics | Members

memory leaks when threading Options
BillPlunkett
Posted: Tuesday, April 19, 2005 8:26:00 AM
Rank: Member
Groups: Member

Joined: 4/14/2005
Posts: 4
Points: 0
I have noticed some memory leaks in the Bitmap/BitmapData classes when I call them from a thread other than the UI thread. Both are documented as thread safe.

You can create a test case by adding the code snippets below to the Main demo. Monitoring the process' memory usage via Task Manager shows evidence of the leak.

Bill

Code:
    // begin test code in FormMain class
    // also need "using System.Threading;"
    private System.Threading.AutoResetEvent testThreadBeginWorkEvent = new AutoResetEvent(false);
    private System.Threading.AutoResetEvent testThreadWorkDoneEvent = new AutoResetEvent(false);
    Thread testThread;
    private void testThreadProc()
    {
      try
      {
        while (true)
        {
          testThreadBeginWorkEvent.WaitOne();
          // by commenting out the entire using block below, the memory leak is plugged
          using (Aurigma.GraphicsMill.BitmapData bitmapData = bitmapViewerMainView.Bitmap.LockBits())
          {
            IntPtr bitmapPtr = bitmapData.Scan0; // using this causes memory leak
            for (int row = 0; row < bitmapViewerMainView.Bitmap.Height; row++)
            {
              bitmapPtr = (IntPtr)((int)bitmapPtr + bitmapData.Stride);
            }
            bitmapViewerMainView.Bitmap.UnlockBits(bitmapData);
          }
          testThreadWorkDoneEvent.Set();
        }
      }
      catch
      {
      }
    }
    private void FormMain_Closing(object sender, System.ComponentModel.CancelEventArgs e)
    {
      testThread.Abort();
      testThread.Join();
    }
    // end test code in FormMain class

    // begin test code in menu item handler, e.g. MenuItemGrayscale_Click()
    // create the test thread
    if (testThread == null)
    {
      testThread = new Thread(new ThreadStart(testThreadProc));
      testThread.Start();
    }
    // signal the thread several times
    for (int i=0; i<1000; i++)
    {
      testThreadBeginWorkEvent.Set();
      testThreadWorkDoneEvent.WaitOne();
    }
    return;
    // end test code in menu item handler

Dmitry
Posted: Wednesday, April 20, 2005 1:37:00 AM
Rank: Advanced Member
Groups: Administration , Member

Joined: 8/3/2003
Posts: 471
Points: 243
Hello,

If you modify your thead procedure as following:

Code:
private void testThreadProc()
{
      try
      {
            while (true)
            {
                  testThreadBeginWorkEvent.WaitOne();
                  using(Aurigma.GraphicsMill.BitmapData bitmapData = bitmapViewerMainView.Bitmap.LockBits())
                  {
                        IntPtr bitmapPtr = bitmapData.Scan0; // using this causes memory leak
                        for (int row = 0; row < bitmapViewerMainView.Bitmap.Height; row++)
                        {
                              bitmapPtr = (IntPtr)((int)bitmapPtr + bitmapData.Stride);
                        }
                        bitmapViewerMainView.Bitmap.UnlockBits(bitmapData);
                  }
                  System.GC.Collect(System.GC.MaxGeneration);
                  testThreadWorkDoneEvent.Set();
            }
      }
      catch
      {
      }
}

memory usage will be reduced. The method System.GC.Collect forces execution of system garbage collector. This demonstrates that all objects are freed correctly but garbage collector "makes a decision" to collect unnecessary objects to free them later.

Sincerely yours,
Dmitry Sevostjanov.
BillPlunkett
Posted: Wednesday, April 20, 2005 10:09:00 AM
Rank: Member
Groups: Member

Joined: 4/14/2005
Posts: 4
Points: 0
I tried this and it does not seem to make any difference. Did you modify the test case and see a difference? If so, any idea what is going on?

Bill
Dmitry
Posted: Wednesday, April 20, 2005 11:52:00 PM
Rank: Advanced Member
Groups: Administration , Member

Joined: 8/3/2003
Posts: 471
Points: 243
I created .NET windows application which contains only your code and inserted the call System.GC.Collect method. No memory leaks was detected. I use perfomance monitor with Working Set counter to detect memory usage.

Could you send us your complete test application and descibe how you measure memory leaks? Also how large memory leaks do you get?

Sincerely yours,
Dmitry Sevostjanov.
Users browsing this topic
Guest


Forum Jump
You cannot post new topics in this forum.
You cannot reply to topics in this forum.
You cannot delete your posts in this forum.
You cannot edit your posts in this forum.
You cannot create polls in this forum.
You cannot vote in polls in this forum.

Main Forum RSS : RSS

YAFVision Theme Created by Jaben Cargman (Tiny Gecko)
Yet Another Forum.net version 1.9.1.6 running under Cuyahoga.
Copyright © 2003-2006 Yet Another Forum.net. All rights reserved.