Solved

Memory leak that I can't find.  Please help!

Posted on 2008-10-19
5
403 Views
Last Modified: 2013-12-12
I am having a problem with an application that I'm working on.  I am fairly certain that it is a memory leak pertaining to bitmaps from my file.  I've tried and tried to find the leak to no avail.  

The application that I'm creating is essentially a go between for two other programs.  The two programs are:
1. An online hosted game
2. A logic application that logs the past outcome of the game and provides suggestions for the next move

My application does the following:
1. Reads the current outcome of the game
2. Passes the information to the logic application and forces the logic app to update with a new suggestion
3. Based on the suggestion, interacts with the online game

The problem is that neither of these applications have any sort of API, and the only way that I can perform this is by strategically locating the applications on the same section of the screen during each play and comparing screen captures to the potential outcomes for each application.

I have my program working properly, except for the fact that after a certain number of iterations of playing the game, it breaks and throws a "Parameter is Not Valid" error when performing a routine screen capture.  From looking online, I've found out that this is a generic error and most likely means that there is a memory leak.  Further supporting the memory leak hypothesis is that if you Try...Catch the error and let the application continue to run, you will get an OutOfMemory error.

I've tried to eliminate this error through hours and hours of debugging, but I'm relatively new trying to catch these errors, and I can't find it.  

I have attached two files:
1. The Action Form doc shows the code of the form that is performing the loop
2. The Helper Information doc shows the class structures and additional helper code

I would greatly appreciate your assistance in getting my code running correctly without errors.  Also, I'd be happy to let anyone look at the source code if that helps in debugging the leak

Thanks!

P.S. I writing in VB.NET, using Framework 3.5, and running Windows XP.  I've tried this on two computers and have the same problem so I don't think it is a hardware issue.  
Action-Form.doc
Helper-Information.doc
0
Comment
Question by:MrSlausen
  • 3
  • 2
5 Comments
 
LVL 10

Expert Comment

by:kdwood
ID: 22771418
MrSlausen,

There are a couple of products that you should try to track this down.  I just loaded the latest version of Ants profiler and was impressed with the information that it gives you.  They have a fully working 10 day demo, which should give you the time you need to evaluate the tool with a real-life problem.  

The other tool is called .NET memory profiler, which also helps you evaluate your memory usage and find leaks.

Here are the links:

http://www.red-gate.com/Products/ants_profiler/index.htm
http://memprofiler.com/

Best regards,

Keith
0
 

Author Comment

by:MrSlausen
ID: 22771457
kdwood: I've used both of these products and was wondering which you think is better for debugging.  My initial take on memprofiler was that it was better for comparing snapshots, but ANTS was a little deeper.

Your thoughts as someone a little more advanced in debugging?
0
 
LVL 10

Expert Comment

by:kdwood
ID: 22772268
I agree with your initial take.  Memprofiler also provides the real-time view which is nice.   I just started using both tools a couple of weeks ago myself, so I am by no means an expert on either.

Please note, I am not expecting points for the product suggestions.  I have an unlimited account so save your points.  

Just out of curiosity, when the application bombs, look in task mgr at your running processes and see how many Excel.exe intances are running.  I've had a problem in the past with the office.interop and the objects not releasing/ending.

I'm assuming you've tried dumbing down the application to just run a couple of functions at a time on each loop.  Then add each function back in one at a time where possible, to try and narrow it down.

How big are the bitmaps from the screen capture typically?

Regards,

Keith
0
 

Author Comment

by:MrSlausen
ID: 22777996
I'll keep the number of instances of running applications when using office.interop in the future.  

I think I fixed the error.  I switched from a FOR..NEXT loop to a DO...LOOP loop and I added a throttle that sleeps the thread for 20 seconds every 1000 turns.  I've tested this on the sample application and not yet on the full application with no exceptions.  I'll be testing on the full application in the next couple of days.

FYI - the bitmaps are typically very small (typically 15x10 and only a few hundred bytes).

If I still have problems in my testing in the next few days, I'll repost.

Thanks Keith for your help!

Regards,

Mark
0
 

Accepted Solution

by:
MrSlausen earned 0 total points
ID: 22832596
This issue has been resolved.  The issue is that the .NET framework has a bug with the CopyFromScreen() method that creates unnecessary handles.  The solution is to go back to the Windows API for the screenshot.  Below is an example of the VB version of the code that I used to correct the issue.

<DllImport("gdi32.dll")> _

Public Shared Function BitBlt(ByVal hdcDest As IntPtr, ByVal xDest As Integer, ByVal yDest As Integer, ByVal wDest As Integer, ByVal hDest As Integer, ByVal hdcSource As IntPtr, ByVal xSrc As Integer, ByVal ySrc As Integer, ByVal rop As Drawing.CopyPixelOperation) As End 
 

<DllImport("user32.dll")> _

Public Shared Function ReleaseDC(ByVal hWnd As IntPtr, ByVal hDc As IntPtr) As Boolean

End Function

    

<DllImport("gdi32.dll")> _

Public Shared Function DeleteDC(ByVal hDc As IntPtr) As IntPtr

End Function

    

<DllImport("gdi32.dll")> _

Public Shared Function DeleteObject(ByVal hDc As IntPtr) As IntPtr

End Function

    

<DllImport("gdi32.dll")> _

Public Shared Function CreateCompatibleBitmap(ByVal hdc As IntPtr, ByVal nWidth As Integer, ByVal nHeight As Integer) As IntPtr

End Function

    

<DllImport("gdi32.dll")> _

Public Shared Function CreateCompatibleDC(ByVal hdc As IntPtr) As IntPtr

End Function

    

<DllImport("gdi32.dll")> _

Public Shared Function SelectObject(ByVal hdc As IntPtr, ByVal bmp As IntPtr) As IntPtr

End Function

    

<DllImport("user32.dll")> _

Public Shared Function GetDesktopWindow() As IntPtr

End Function

    

<DllImport("user32.dll")> _

Public Shared Function GetWindowDC(ByVal ptr As IntPtr) As IntPtr

End Function
 

Public Shared Function CaptureImage(ByVal width As Integer, ByVal height As Integer, ByVal x As Integer, ByVal y As Integer) As System.Drawing.Bitmap

        

Dim sz As Rectangle

sz.Width = width

sz.Height = height
 

Dim hDesk As IntPtr = appMain.GetDesktopWindow()

Dim hSource As IntPtr = appMain.GetWindowDC(hDesk)

Dim hDest As IntPtr = appMain.CreateCompatibleDC(hSource)

Dim hBmp As IntPtr = appMain.CreateCompatibleBitmap(hSource, sz.Width, sz.Height)

Dim hOldBmp = appMain.SelectObject(hDest, hBmp)
 

Dim b As Boolean = appMain.BitBlt(hDest, 0, 0, sz.Width, sz.Height, hSource, x, y, CopyPixelOperation.SourceCopy)
 

Dim bmp As Bitmap = Bitmap.FromHbitmap(hBmp)

appMain.SelectObject(hDest, hOldBmp)
 

appMain.DeleteObject(hBmp)

appMain.DeleteDC(hDest)

appMain.ReleaseDC(hDesk, hSource)

bmp.Save("c:\working\Test.bmp")

Return bmp

bmp.Dispose()

    

End Function

Open in new window

0

Featured Post

Backup Your Microsoft Windows Server®

Backup all your Microsoft Windows Server – on-premises, in remote locations, in private and hybrid clouds. Your entire Windows Server will be backed up in one easy step with patented, block-level disk imaging. We achieve RTOs (recovery time objectives) as low as 15 seconds.

Join & Write a Comment

It was really hard time for me to get the understanding of Delegates in C#. I went through many websites and articles but I found them very clumsy. After going through those sites, I noted down the points in a easy way so here I am sharing that unde…
Workplace bullying has increased with the use of email and social media. Retain evidence of this with email archiving to protect your employees.
The viewer will learn common shortcuts with easy ways to remember them. The viewer will then learn where to find all of the keyboard shortcuts, how to create/change them, and how to speed up their workflow.
Video by: Tony
This video teaches viewers how to export a project from Adobe Premiere Pro and the various file types involved.

743 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

10 Experts available now in Live!

Get 1:1 Help Now