Rank: Member
Groups: Guest
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
|
|
|
|
Rank: Advanced Member
Groups: Guest
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 |
|
|
|
|
Rank: Member
Groups: Guest
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
|
|
|
|
Rank: Advanced Member
Groups: Guest
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? |
|
|
|
|
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.