Solved

Memory eating api/variable help VB6

Posted on 2004-08-11
11
392 Views
Last Modified: 2013-11-13
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
Comment
Question by:bluedragon99
11 Comments
 
LVL 1

Author Comment

by:bluedragon99
Comment Utility
Hsnap is a Long btw
0
 
LVL 1

Author Comment

by:bluedragon99
Comment Utility
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
 
LVL 1

Author Comment

by:bluedragon99
Comment Utility
also getting a bunch of squares appended on my processes variable, Ideas?
0
 
LVL 1

Author Comment

by:bluedragon99
Comment Utility
 szExeFile As String * 260       ' MAX_PATH

in the module what the hell is the * 260 for?  its causing the garbage characters
0
 
LVL 3

Expert Comment

by:travisjhall
Comment Utility
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
How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

 
LVL 3

Expert Comment

by:travisjhall
Comment Utility
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
 
LVL 3

Expert Comment

by:travisjhall
Comment Utility
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
 
LVL 3

Accepted Solution

by:
Stimphy earned 250 total points
Comment Utility
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
 
LVL 2

Expert Comment

by:amg42
Comment Utility
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
 
LVL 3

Expert Comment

by:travisjhall
Comment Utility
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
 
LVL 1

Author Comment

by:bluedragon99
Comment Utility
It was the Dim'ing in the loop :)
0

Featured Post

IT, Stop Being Called Into Every Meeting

Highfive is so simple that setting up every meeting room takes just minutes and every employee will be able to start or join a call from any room with ease. Never be called into a meeting just to get it started again. This is how video conferencing should work!

Join & Write a Comment

Suggested Solutions

This is an explanation of a simple data model to help parse a JSON feed
This is about my first experience with programming Arduino.
Viewers will learn how to properly install Eclipse with the necessary JDK, and will take a look at an introductory Java program. Download Eclipse installation zip file: Extract files from zip file: Download and install JDK 8: Open Eclipse and …
In this fourth video of the Xpdf series, we discuss and demonstrate the PDFinfo utility, which retrieves the contents of a PDF's Info Dictionary, as well as some other information, including the page count. We show how to isolate the page count in a…

762 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

9 Experts available now in Live!

Get 1:1 Help Now