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

Posted on 2008-10-19
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


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.  
Question by:MrSlausen
  • 3
  • 2
LVL 10

Expert Comment

ID: 22771418

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:

Best regards,


Author Comment

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?
LVL 10

Expert Comment

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?



Author Comment

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!



Accepted Solution

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.ReleaseDC(hDesk, hSource)
Return bmp
End Function

Open in new window


Featured Post

Master Your Team's Linux and Cloud Stack!

The average business loses $13.5M per year to ineffective training (per 1,000 employees). Keep ahead of the competition and combine in-person quality with online cost and flexibility by training with Linux Academy.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Title # Comments Views Activity Move a class from Solution Items to a project 2 23
FreeFileSync Batch Files 1 8
Edit image captured by printScreen 4 21
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…
The article will include the best Data Recovery Tools along with their Features, Capabilities, and their Download Links. Hope you’ll enjoy it and will choose the one as required by you.
This video shows how use content aware, what it’s used for, and when to use it over other tools.
An overview on how to enroll an hourly employee into the employee database and how to give them access into the clock in terminal.

803 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