Tengo una fuga de memória grave en una aplicación, y es debido a una Class de terceros que estoy usando...
Este simple código aloja entre 100-200kb de RAM cada segundo
Public Class Form1
Dim isbinded As Boolean = False
Dim Winamp As clsWACC = New clsWACC
Dim WithEvents mytimer As New Timer With {.Interval = 50, .Enabled = True}
Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles mytimer.Tick
isbinded = Winamp.Bind()
' Label1.Text = isbinded
' isbinded = Nothing
End Sub
End Class
Necesito usar un Timer rápido de menos de 50 ms, pero simplemente por curiosidad si aumento el Timer a 1000 ms la ram sigue subiendo sin pausa, aunque sube sólo 8 kb cada segundo.
He intentado examinar y corregir la Class pero no encuentro el fallo, esta es la parte de la Class que manipula el code de arriba:
Public Sub New(ByVal handle As IntPtr, ByVal str As String)
'opens the process
hWinamp = OpenProcess(DAccess.PROCESS_ALL_ACCESS, False, waPID)
'If hWinamp.Equals(IntPtr.Zero) Then
' 'exception
'End If
remStr = str
remoteBuf = AllocWinamp(handle, Convert.ToUInt32(str.Length + 1))
Dim localBuf As IntPtr = Marshal.StringToHGlobalAnsi(str)
WriteProcessMemory(hWinamp, remoteBuf, localBuf, str.Length + 1, Nothing)
Marshal.FreeHGlobal(localBuf)
End Sub
Dim path As String = Nothing
Dim regKey As RegistryKey = Registry.CurrentUser.OpenSubKey("Software\Winamp", False)
'Binds to WinAmp
Public Function Bind() As Boolean
Return Bind("")
End Function
Public Function Bind(ByVal PathToExecutable As String) As Boolean
hWnd_Winamp = WinAPI.FindWindow(lpClassName, Nothing)
'waProcess = New Process
waProcess.EnableRaisingEvents = True
'If WinAmp window handle not found, try to launch it
If hWnd_Winamp.Equals(IntPtr.Zero) Then
'if path was not specified, try to find it in the Windows registry
If PathToExecutable = "" Then
'Dim path As String
'regKey = Registry.CurrentUser
'regKey = regKey.OpenSubKey("Software\Winamp", False)
If regKey IsNot Nothing Then
path = Convert.ToString(regKey.GetValue(""))
waProcess.StartInfo.FileName = path & "\Winamp.exe"
regKey.Close()
Else
Return False
End If
Else
waProcess.StartInfo.FileName = PathToExecutable
End If
Try
waProcess.Start()
Catch ex As System.ComponentModel.Win32Exception When ex.ErrorCode = -2147467259
Debug.
WriteLine("Executable not found") Return False
Catch ex As Exception
Debug.
WriteLine("unknown exception") Return False
End Try
waProcess.WaitForInputIdle()
hWnd_Winamp = waProcess.MainWindowHandle()
waPID = waProcess.Id
Else
'WinAmp handle found
'now bind to WinAmp process
'get PID from hWnd
WinAPI.GetWindowThreadProcessId(hWnd_Winamp, waPID)
If waPID = 0 Then
Return False
End If
waProcess = Process.GetProcessById(waPID)
waProcess.EnableRaisingEvents = True
hWnd_Playlist = GetHWND(WinampWindow.Playlist)
hWnd_Equalizer = GetHWND(WinampWindow.Equalizer)
hWnd_Video = GetHWND(WinampWindow.Video)
Return True
End If
'if hWnd of the main window is still zero,
'it was not possible to launch or bind to WinAmp
If hWnd_Winamp.Equals(IntPtr.Zero) Then
Return False
Else
hWnd_Playlist = GetHWND(WinampWindow.Playlist)
hWnd_Equalizer = GetHWND(WinampWindow.Equalizer)
hWnd_Video = GetHWND(WinampWindow.Video)
Return True
End If
End Function
Pero la primera condición no se cumple, es decir, solo se manipula esta parte de la función Bind:
If hWnd_Winamp.Equals(IntPtr.Zero) Then
' NADA
Else
'WinAmp handle found
'now bind to WinAmp process
'get PID from hWnd
WinAPI.GetWindowThreadProcessId(hWnd_Winamp, waPID)
If waPID = 0 Then
Return False
End If
waProcess = Process.GetProcessById(waPID)
waProcess.EnableRaisingEvents = True
hWnd_Playlist = GetHWND(WinampWindow.Playlist)
hWnd_Equalizer = GetHWND(WinampWindow.Equalizer)
hWnd_Video = GetHWND(WinampWindow.Video)
Return True
End If
hWnd_Winamp es un IntPtr
waProcess es un Process (el cual he probado a liberarlo pero sigue pasando lo mismo...)
waPID es un Integer
hWnd_Playlist es un IntPtr
hWnd_Equalizer es un IntPtr
hWnd_Video es un IntPtr
...y GetWindowThreadProcessId es esta función:
'======================== =========================
'====================== GetWindowThreadProcessId =======================
'======================== =========================
'Retrieves the identifier of the thread that created the specified window
'and, optionally, the identifier of the process that created the window.
<DllImport("user32.dll", SetLastError:=True)> _
Public Shared Function GetWindowThreadProcessId( _
ByVal hwnd As IntPtr, _
ByRef lpdwProcessId As Integer) As Int32
End Function
y esta la función GetHWND:
Private Shared Function GetHWND(ByVal Window As WinampWindow) As IntPtr
Return SendWA_IPC(Window, Message.IPC_GETWND)
End Function
Private Shared Function SendWA_IPC(ByVal param As Int64, ByVal MessageName As Message) As IntPtr
Return WinAPI.SendMessage(hWnd_Winamp, WinAPI.Msg.WM_USER, IntPtr.op_Explicit(param), IntPtr.op_Explicit(MessageName))
End Function
'=============================== ===============================
'============================= SendMessage =============================
'=============================== ===============================
'Sends the specified message to a window or windows. It calls the window
'procedure for the specified window and does not return until the window
'procedure has processed the message.
<DllImport("user32.dll", SetLastError:=True, CharSet:=CharSet.Auto)> _
Public Shared Function SendMessage(ByVal hWnd As IntPtr, _
ByVal Msg As Msg, _
ByVal wParam As IntPtr, _
ByVal lParam As IntPtr) As IntPtr
End Function
¿Alguna sugerencia?Gracias...