Go Premium for a chance to win a PS4. Enter to Win

x
  • Status: Solved
  • Priority: Medium
  • Security: Public
  • Views: 423
  • Last Modified:

Memory eating api/variable help VB6

The problem is the hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0) Line is chewing up memory like crazy.  If I comment that line out problem goes away (but kills the process checker of course).  Is there a way to clear out the variable hSnap?  Tried the ways I know without success.  This code below is in a timer control.  HELP!!


Heres the code timer1 code:

  Dim f As Long, sname As String
         Dim hSnap As Long, proc As PROCESSENTRY32
         hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
         If hSnap = hNull Then Exit Sub
         proc.dwSize = Len(proc)

         ' Iterate through the processes
         f = Process32First(hSnap, proc)
         Do While f
               some code here
         f = Process32Next(hSnap, proc)
         Loop
           


Heres the module it uses:


      Public Declare Function Process32First Lib "kernel32" ( _
         ByVal hSnapshot As Long, lppe As PROCESSENTRY32) As Long

      Public Declare Function Process32Next Lib "kernel32" ( _
         ByVal hSnapshot As Long, lppe As PROCESSENTRY32) As Long

      Public Declare Function CloseHandle Lib "Kernel32.dll" _
         (ByVal Handle As Long) As Long

      Public Declare Function OpenProcess Lib "Kernel32.dll" _
        (ByVal dwDesiredAccessas As Long, ByVal bInheritHandle As Long, _
            ByVal dwProcId As Long) As Long

      Public Declare Function EnumProcesses Lib "psapi.dll" _
         (ByRef lpidProcess As Long, ByVal cb As Long, _
            ByRef cbNeeded As Long) As Long

      Public Declare Function GetModuleFileNameExA Lib "psapi.dll" _
         (ByVal hProcess As Long, ByVal hModule As Long, _
            ByVal ModuleName As String, ByVal nSize As Long) As Long

      Public Declare Function EnumProcessModules Lib "psapi.dll" _
         (ByVal hProcess As Long, ByRef lphModule As Long, _
            ByVal cb As Long, ByRef cbNeeded As Long) As Long

      Public Declare Function CreateToolhelp32Snapshot Lib "kernel32" ( _
         ByVal dwFlags As Long, ByVal th32ProcessID As Long) As Long

      Public Declare Function GetVersionExA Lib "kernel32" _
         (lpVersionInformation As OSVERSIONINFO) As Integer

      Public Type PROCESSENTRY32
         dwSize As Long
         cntUsage As Long
         th32ProcessID As Long           ' This process
         th32DefaultHeapID As Long
         th32ModuleID As Long            ' Associated exe
         cntThreads As Long
         th32ParentProcessID As Long     ' This process's parent process
         pcPriClassBase As Long          ' Base priority of process threads
         dwFlags As Long
         szExeFile As String * 260       ' MAX_PATH
      End Type

      Public Type OSVERSIONINFO
         dwOSVersionInfoSize As Long
         dwMajorVersion As Long
         dwMinorVersion As Long
         dwBuildNumber As Long
         dwPlatformId As Long           '1 = Windows 95.
                                        '2 = Windows NT

         szCSDVersion As String * 128
      End Type

      Public Const PROCESS_QUERY_INFORMATION = 1024
      Public Const PROCESS_VM_READ = 16
      Public Const MAX_PATH = 260
      Public Const STANDARD_RIGHTS_REQUIRED = &HF0000
      Public Const SYNCHRONIZE = &H100000
      'STANDARD_RIGHTS_REQUIRED Or SYNCHRONIZE Or &HFFF
      Public Const PROCESS_ALL_ACCESS = &H1F0FFF
      Public Const TH32CS_SNAPPROCESS = &H2&
      Public Const hNull = 0
0
bluedragon99
Asked:
bluedragon99
1 Solution
 
bluedragon99Author Commented:
Hsnap is a Long btw
0
 
bluedragon99Author Commented:
28 bytes of memory are being used everytime the timer runs by that line of code.  and it doesn't come back on exit.
0
 
bluedragon99Author Commented:
also getting a bunch of squares appended on my processes variable, Ideas?
0
Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

 
bluedragon99Author Commented:
 szExeFile As String * 260       ' MAX_PATH

in the module what the hell is the * 260 for?  its causing the garbage characters
0
 
travisjhallCommented:
CreateToolhelp32Snapshot returns a handle to a snapshot, something that I'm not familiar with but which obviously uses a relatively large amount of memory. That snapshot will be maintained by the OS, and will probably be destroyed when all handles to it have been closed - that's usually how handles work.

So, are you closing the handle at some stage?
CloseHandle hSnap
or
If CloseHandle(hSnap) = 0 Then
  ' put some error checking code here because CloseHandle has failed - GetLastError API function should probably be involved
End If

Because I don't see something similar to that in what you have posted.
0
 
travisjhallCommented:
BTW, CreateToolhelp32Snapshot won't return 0 when it fails. It returns INVALID_HANDLE_VALUE on failure. The definition is:
Public Const INVALID_HANDLE_VALUE = -1

You might like to add that line to your module in place of the hNull definition (or as well as, if hNull is used for other things), and change "If hSnap = hNull Then Exit Sub" to " If hSnap = INVALID_HANDLE_VALUE Then Exit Sub".

According to the Platform SDK, anyway.

When using API functions, the Platform SDK is your friend. Get it. Use it. Lots.
0
 
travisjhallCommented:
The * 260 makes the string a fixed-length string of 260 characters. This results in the memory for those characters being allocated immediately, rather than as-needed like most strings in VB. Thus, when the API function works with this string, it has an appropiate buffer ready to receive its data. If you don't have this, the API function will try to overwrite a section of memory that isn't allocated for its use, because you haven't assigned the appropriate memory. Leave that "* 260" alone.

And the fixed-length nature of the string isn't causing the garbage characters. The garbage characters are just what happen to be used in the extra bytes of memory that aren't actually used by the API function. I'm guessing here, but I think you will find that at least the first of those "garbage characters" is a null character. If you need to work with the path of the exe file, you can do something to get the bit you want out of that string, like say:
Dim sExeFile As String
Dim lPos As Long
lPos = InStr(proc.sExeFile, vbNullChar)
If lPos = 0 Then
  sExeFile = proc.sExeFile
Else
  sExeFile = Left(proc.sExeFile, lPos)
End If

But I haven't tested that, so be a bit careful.
0
 
StimphyCommented:
I have run your code and yes it does use memory... BUT I think if you just declare the variable type outside of the timer sub... your problems will go away.  I have run the code below with out the memory usage going up.

I believe that the allocated memory space for Proc is never deallocated with your code.  In the sample below, Proc is only defined once and is never defiined again.  Therefore, you dont get excessive memory usage.

'Try This:
'Top of Form

Dim Proc As PROCESSENTRY32

'Your Code...................

Private Sub Timer1_Timer()
 Dim f As Long, sname As String
         Dim hSnap As Long
         hSnap = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0)
         If hSnap = hNull Then Exit Sub
         proc.dwSize = Len(Proc)

         ' Iterate through the processes
         f = Process32First(hSnap, Proc)
         Do While f
               some code here
         f = Process32Next(hSnap, Proc)
         Loop
End Sub

Best Regaurds,
Dave
0
 
amg42Commented:
From MSDN:

     To close a snapshot call the CloseToolhelp32Snapshot function.
     Do not call the CloseHandle function to close the snapshot call.
     Calling CloseHandle to close the snapshot call generates a memory leak.

So, maybe you can call CloseToolhelp32Snapshot(hSnap) after your Do...Loop?
0
 
travisjhallCommented:
CloseHandle is the correct method of freeing memory allocated by CreateToolhelp32Snapshot under most versions of Windows. However, under Windows CE, CloseToolhelp32Snapshot is the correct method, and a memory leak will occur under Windows CE if you use CloseHandle instead. CloseToolhelp32Snapshot is only available under Windows CE, not any other OS.

In addition, a memory leak will occur using CreateToolhelp32Snapshot under Windows 2000 unless an appropriate hotfix is applied (or maybe that's been incorporated into a service pack by now? I don't know, I've lost track of how many win2K service packs are out). See http://support.microsoft.com/default.aspx?scid=kb;en-us;831712 for more details.
0
 
bluedragon99Author Commented:
It was the Dim'ing in the loop :)
0

Featured Post

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Tackle projects and never again get stuck behind a technical roadblock.
Join Now