Welcome Guest! You need to login or register to make posts.

Notification

Icon
Error

Options
Go to last post Go to first unread
BillPlunkett  
#1 Posted : Tuesday, April 19, 2005 12:26:00 AM(UTC)
BillPlunkett

Rank: Member

Groups: Member
Joined: 4/14/2005(UTC)
Posts: 4

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

Edited by user Monday, December 24, 2007 3:40:58 PM(UTC)  | Reason: Not specified

Dmitry  
#2 Posted : Tuesday, April 19, 2005 5:37:00 PM(UTC)
Dmitry

Rank: Advanced Member

Groups: Member, Administration, Moderator
Joined: 8/3/2003(UTC)
Posts: 1,070

Thanks: 1 times
Was thanked: 12 time(s) in 12 post(s)
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.

Edited by user Monday, December 24, 2007 3:41:32 PM(UTC)  | Reason: Not specified

Sincerely yours,
Dmitry Sevostyanov

UserPostedImage Follow Aurigma on Twitter!
BillPlunkett  
#3 Posted : Wednesday, April 20, 2005 2:09:00 AM(UTC)
BillPlunkett

Rank: Member

Groups: Member
Joined: 4/14/2005(UTC)
Posts: 4

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  
#4 Posted : Wednesday, April 20, 2005 3:52:00 PM(UTC)
Dmitry

Rank: Advanced Member

Groups: Member, Administration, Moderator
Joined: 8/3/2003(UTC)
Posts: 1,070

Thanks: 1 times
Was thanked: 12 time(s) in 12 post(s)
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 Sevostyanov

UserPostedImage Follow Aurigma on Twitter!
Users browsing this topic
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.