Reputation: 12831
I am using the win32api to get a list of all window titles. I need the list to be refreshed every few seconds and thats the problem: The memory usage of the app is increasing every time I call EnumWindowsCallback.
Here is a working demo: Run the code and see in the task manager how the memory usage of this app increases. Press RETURN to call the function again.
Imports System.Runtime.InteropServices
Imports System.Text
Class Example
Shared Sub Main()
For a = 1 To 5
Console.WriteLine("--------- (RUN NR " & a & ") PRESS RETURN")
Console.ReadLine()
Win32API.EnumWindowsDllImport(New Win32API.EnumWindowsCallback(AddressOf FillActiveWindowsList), 0)
Next
Console.WriteLine("READY!")
Console.ReadLine()
End Sub
Shared Function FillActiveWindowsList(ByVal _hWnd As IntPtr, ByVal lParam As IntPtr) As Boolean
Dim windowText As New StringBuilder(255)
Win32API.GetWindowText(_hWnd, windowText, 255)
Console.WriteLine(windowText)
Return True
End Function
End Class
Public Class Win32API
Public Delegate Function EnumWindowsCallback(hWnd As Integer, lParam As Integer) As Boolean
<DllImport("user32.dll", EntryPoint:="EnumWindows", SetLastError:=True, CharSet:=CharSet.Ansi, ExactSpelling:=True, CallingConvention:=CallingConvention.StdCall)> _
Public Shared Function EnumWindowsDllImport(callback As EnumWindowsCallback, lParam As Integer) As Integer
End Function
<DllImport("user32.dll", EntryPoint:="GetWindowTextA")> _
Public Shared Sub GetWindowText(hWnd As Integer, lpstring As StringBuilder, nMaxCount As Integer)
End Sub
End Class
at the beginning my EXE is about 3MB big, but after 5 function calls it is increased to 6 MB (and stays there) The problem is that it causes some crashes in my main application if the memory usage gets over 6 MB. The example above should not crash.
Do you see a problem here? Maybe there is a problem with the data types? or maybe it is a bug? Any help would be appreciated.
Upvotes: 0
Views: 510
Reputation: 278
Replace This Code
For a = 1 To 5
Console.WriteLine("--------- (RUN NR " & a & ") PRESS RETURN")
Console.ReadLine()
Win32API.EnumWindowsDllImport(New Win32API.EnumWindowsCallback(AddressOf FillActiveWindowsList), 0)
Next
with this code
dim a as integer = 1
DoitFive:
Console.WriteLine("--------- (RUN NR " & a & ") PRESS RETURN")
Console.ReadLine()
Win32API.EnumWindowsDllImport(New Win32API.EnumWindowsCallback(AddressOf FillActiveWindowsList), 0)
a += 1
if a <> 5 then goto DoitFive
Becouse the Code that you working with is holding the process of your EXE until loop 5 Times and that will make it 6MB Size.
Upvotes: 0
Reputation: 941515
That's not possible, you won't get an OutOfMemoryException until you've consumed at least 1500 MB. You are a factor of x250 removed from explaining the "crash" with a leak. The 3 MB increase is simply the garbage collected heap growing to meet your program's demands. Seeing it stabilize is entirely normal as well, the ultimate hint that you don't have a leak.
Surely you get a better diagnostic than just "it crashed". You do have bugs in your code, the pinvoke declarations are wrong. The lParam arguments are IntPtr, not int. This can cause various amount of upheaval, you'd normally get a warning from the PInvokeStackImbalance Managed Debugger Assistant. Use the pinvoke.net website to get better ones. And do show in detail what that "crash" looks like in the debugger if you need more help.
Upvotes: 2