Announcement

Collapse

Forum Guidelines

This forum is for finished source code that is working properly. If you have questions about this or any other source code, please post it in one of the Discussion Forums, not here.
See more
See less

Add Process Memory Usage Report to any program

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • Add Process Memory Usage Report to any program

    #INCLUDE FILE FOR ANY USING PROGRAM

    Code:
     
    ' FILE : Process_memoryInfo.INC
    ' File to be #INCLUDEd in programs to get memory usage info about the current process
    '=================================================================================================
    ' returns: TRUE: S has CRLF delimited process memory info, FALSE S contains message why it doesn't
    ' FUNCTION GetProcessMemoryStatistics (S AS STRING) AS LONG
    '-------------------------------------------------------------------------------------------------
    '-------------------------------------------------------------------------------------------------
    ' PSAPI header conversions Courtesy: Jose Roca 11/2002 at
    ' http://www.powerbasic.com/support/forums/Forum7/HTML/001630.html 
    ' The PSAPI functions are only supported on platform 5 machines. THis code detects OS and acts accordingly
    ' This file contains only the DECLARES, UDTs and functions necessary to
    ' support the GetProcessMemoryInfo function
    ' 1/11/04
    ' Michael Mattias Racine WI
    ' Placed in public domain by author 1/12/04
    ' Tested OK on Win/98 1/11/04 (not that that is a terribly useful test.)
    ' Tested by others on other OS; See http://www.powerbasic.com/support/forums/Forum6/HTML/003994.html 
    ' Compiler       PB/Windows v 7.02
    ' Win32API.INC   May 9 2002
    
    ' STRUCTURE RETURNED BY GetProcessMemoryInfo
    '  The "WorkingSetSize" members are the best indicator of a process' total memory usage.
    '
    TYPE W_PROCESS_MEMORY_COUNTERS
       cb                         AS DWORD   '// Size of the structure, in bytes.
       PageFaultCount             AS DWORD   '// Number of page faults.
       PeakWorkingSetSize         AS DWORD   '// Peak working set size.
       WorkingSetSize             AS DWORD   '// Current working set size.
       QuotaPeakPagedPoolUsage    AS DWORD   '// Peak paged pool usage.
       QuotaPagedPoolUsage        AS DWORD   '// Current paged pool usage.
       QuotaPeakNonPagedPoolUsage AS DWORD   '// Peak nonpaged pool usage.
       QuotaNonPagedPoolUsage     AS DWORD   '// Current nonpaged pool usage.
       PagefileUsage              AS DWORD   '// Current space allocated for the pagefile.
                                             '// Those pages may or may not be in memory.
       PeakPagefileUsage          AS DWORD   '// Peak space allocated for the pagefile.
    END TYPE
    
    #IF 0
    ' DECLARE FOR GetProcessMemoryInfo. Note this DECLARE is not used in this file, it
    ' is supplied only for reference.
    DECLARE FUNCTION GetProcessMemoryInfo LIB "PSAPI.DLL" ALIAS "GetProcessMemoryInfo" ( _
            BYVAL hProcess        AS DWORD, _
                  ppsmemCounters  AS PROCESS_MEMORY_COUNTERS, _
            BYVAL cb              AS DWORD _
    ) AS LONG
    #ENDIF
    ' DECLARE FOR USE WITH CALL DWORD IN THIS INCLUDE FILE
    DECLARE FUNCTION W_GetProcessMemoryInfo _
          ( BYVAL             hProcess AS DWORD, _
            ppsmemCounters             AS W_PROCESS_MEMORY_COUNTERS, _
            BYVAL             cb       AS DWORD _
          ) AS LONG
    
    #IF NOT %DEF(%WINAPI)
      #INCLUDE "WIN32API.INC"
    #ENDIF
    $PSAPI_LIBNAME               =   "PSAPI.DLL"
    $PSAPI_GETPROCESSMEMORYINFO  = "GetProcessMemoryInfo"
    TYPE FormatWPMCType
        Statistic       AS STRING *  40
        Value           AS STRING *  16
        eol             AS STRING *   2   ' end of line
    END TYPE
    
    FUNCTION Formatted_WPMC (WPMC AS W_PROCESS_MEMORY_COUNTERS) AS STRING
        LOCAL w AS STRING, mask AS STRING, FW AS FormatWpmcType
        mask   = "* #,"      ' format for integers
        w      = ""
        FW.Eol               =  $CR & $LF           ' or $CRLF if sufficient compiler version
        LSET FW.Statistic    = "Page Fault Count"
        RSET FW.Value        =  FORMAT$(WPMC.PageFaultCount, mask)
        w                    =  w & PEEK$(VARPTR(FW), SIZEOF(FW))
        LSET FW.Statistic    =  "Peak Working Set Size"
        RSET FW.Value        =  FORMAT$(WPMC.PeakWorkingSetSize, mask)
        w                    =  w & PEEK$(VARPTR(FW), SIZEOF(FW))
        LSET FW.Statistic    =  "Current Working Set Size"
        RSET FW.Value        =  FORMAT$(WPMC.WorkingSetSize, mask)
        w                    =  w & PEEK$(VARPTR(FW), SIZEOF(FW))
        LSET FW.Statistic    =  "Quota Peak Paged Pool Usage"
        RSET FW.Value        =  FORMAT$(WPMC.QuotaPeakPagedPoolUsage, mask)
        w                    =  w & PEEK$(VARPTR(FW), SIZEOF(FW))
        LSET FW.Statistic    =  "Current Quota Paged Pool Usage"
        RSET FW.Value        =  FORMAT$(WPMC.QuotaPagedPoolUsage, mask)
        w                    =  w & PEEK$(VARPTR(FW), SIZEOF(FW))
        LSET FW.Statistic    =  "Quota Peak Non-Paged Pool Usage"
        RSET FW.Value        =  FORMAT$(WPMC.QuotaPeakNonPagedPoolUsage, mask)
        w                    =  w & PEEK$(VARPTR(FW), SIZEOF(FW))
        LSET FW.Statistic    =  "Current Quota Non-Paged Pool Usage"
        RSET FW.Value        =  FORMAT$(WPMC.QuotaNonPagedPoolUsage, mask)
        w                    =  w & PEEK$(VARPTR(FW), SIZEOF(FW))
        LSET FW.Statistic    =  "Peak Page File Usage"
        RSET FW.Value        =  FORMAT$(WPMC.PeakPageFileUsage, mask)
        w                    =  w & PEEK$(VARPTR(FW), SIZEOF(FW))
        LSET FW.Statistic    =  "Current Page File Usage"
        RSET FW.Value        =  FORMAT$(WPMC.PageFileUsage, mask)
        w                    =  w & PEEK$(VARPTR(FW), SIZEOF(FW))
        FUNCTION             =  RTRIM$(W, ANY CHR$(13,10))   'remove trailing CRLF
    END FUNCTION
    
    ' MAIN CALLED FUNCTION
    ' returns: TRUE: S has CRLF delimited process memory info, FALSE S contains messages why it doesn't
    FUNCTION GetProcessMemoryStatistics (S AS STRING) AS LONG
        LOCAL hProcess AS DWORD,  lret AS LONG, cb AS LONG, isP5 AS LONG
        LOCAL WPMC     AS W_PROCESS_MEMORY_COUNTERS
        LOCAL OSV AS OSVERSIONINFO
        LOCAL szLibName    AS ASCIIZ * %MAX_PATH, szProcName AS ASCIIZ * %MAX_PATH
        LOCAL hLIB         AS LONG,  dwAddr AS DWORD
        FUNCTION                  =  %FALSE         ' don't set to true until we have the info
        s                         = ""
        ' get the OS Version and decide if we are on a platform 5 machine
        OSV.dwOsVersionInfoSize   =  SIZEOF(OSV)
        lRet                     &nbmage  GetVersionEx (OSV)
        IF ISTRUE lRet THEN
            IsP5                  =  (OSV.dwPlatformID  = %VER_PLATFORM_WIN32_NT)
        ELSE
            S = "Can't get operating system version.. this is really bad!"
            EXIT FUNCTION
        END IF
        ' if this is a platform 5 machine..
        ' Lie about OS for test on Win/98, should return unable to load library, it does.
        ' isP5     = %TRUE
        IF ISTRUE  isP5 THEN
            ' Get the address of the function in PSAPI.DLL
            szLibName      = $PSAPI_LIBNAME
            szProcName     = $PSAPI_GETPROCESSMEMORYINFO
            hLib           = LoadLibrary (szLibName)
            IF ISTRUE  hLIB THEN
                dwAddr     =  GetProcAddress (hLib, szProcName)
                IF ISTRUE dwAddr THEN
                    hProcess      = GetCurrentProcess
                    cb            = SIZEOF(WPMC)
                    ' call the function
                    CALL DWORD dwAddr USING W_GetProcessMemoryInfo (hPRocess, WPMC,cb) TO lret
                    IF ISTRUE lret THEN     ' function succeeded, format the WPMC structure
                        S     = Formatted_WPMC (WPMC)
                        FUNCTION   = %TRUE
                    ELSE
                        S     = "GetProcessMemoryInfoFailed"
                    END IF
                ELSE
                    S         = "Can't Get Address for " & szProcName
                END IF
                FreeLibrary      hLib
            ELSE
                S             = "Can't load library " & szLibName
            END IF
         ELSE
                s             = "Process Memory Information N/A on this operating system."
                #IF 0
                ' for test of formatting only on Win 9x..
                WPMC.PageFaultCount              = 1234567890
                WPMC.PeakWorkingSetSize          = 1234567891
                WPMC.WorkingSetSize              = 1234567892
                WPMC.QuotaPeakPagedPoolUsage     = 1234567893
                WPMC.QuotaPagedPoolUsage         = 1234567894
                WPMC.QuotaPeakNonPagedPoolUsage  = 1234567895
                WPMC.QuotaNonPagedPoolUsage      = 1234567896
                WPMC.PeakPageFileUsage           = 1234567897
                WPMC.PageFileUsage               = 1234567898
                s             = Formatted_WPMC (WPMC)
                #ENDIF
         END IF
    
    END FUNCTION
    ' // END OF FILE 
    
    
     
    [b] DEMO PROGRAM SHOWING HOW TO USE 
    
     
    ' FILE : Process_memoryInfo.bas
    ' Demo of Function GetProcessMemoryStatistics in #INCLUDE file process_memoryinfo.inc
    ' Author: Michael Mattias Racine WI    1-12-04
    ' Usage:  Placed in public domain by author 1-13-04
    ' compiler:      PB/Windows v 7.02
    ' Win32API.INC   May 9 2002  (Called in by #INCLUDE file if not already included)
    ' tested on:     Windows/98, Windows 2000, Windows XP#COMPILE      EXE
    #DEBUG        ERROR ON
    #REGISTER     NONE
    #TOOLS        OFF
    #DIM          ALL
    
    #INCLUDE  "WIN32API.INC"
    #INCLUDE "process_memoryinfo.inc"
    ' Contains: FUNCTION GetProcessMemoryStatistics (S AS STRING) AS LONG
    ' returns: TRUE: S has CRLF delimited process memory info, FALSE S contains message why it doesn't
    FUNCTION PBMAIN () AS LONG
      LOCAL s AS STRING, l AS LONG, Z() AS STRING * 1024
      LOCAL hFile AS LONG, szFile AS ASCIIZ * %MAX_PATH
      LOCAL pID   AS DWORD, sBuff AS STRING
      
      
        szFile    = "Process_memory_Statistics.txt"
        
        hFile    = FREEFILE
        OPEN       szFile  FOR OUTPUT AS hFile
        PID      = GetCurrentProcessID
        sBUff    = "Process Memory Statistics for Process ID " & STR$(PID) & " on " & DATE$ & " at " & TIME$
        PRINT      #hFile, sBUff
        PRINT      #hFile,
        
        
      ' allocate   50 mb of memory and get statistics..
        REDIM       Z (50 * 1024)
        L        = GetProcessMemoryStatistics (s)
        
        sBUff    = "Process Memory Statistics with Array Allocated"
        PRINT #hFile, sBuff
        PRINT #hFile, s
        PRINT #hFile,
        
        
      ' De-allocate the memory...
        ERASE Z()
      ' ... and get 'end of job' statistics.
      ' We should see 'peak' numbers much less than 'current' numbers
      ' (and somewhere approximately 50 Mb of difference)
        L        = GetProcessMemoryStatistics (s)
        sBUff    = "Process Memory Statistics with Array De-Allocated"
        PRINT #hFile, sBuff
        PRINT #hFile, s
        PRINT #hFile,
        sBuff    = "END OF REPORT"
        PRINT #hFile, sBuff
        
        CLOSE hFile
        
        PID = SHELLExecute (GetDesktopWindow, "open", szFile, BYVAL %NULL, BYVAL %NULL, %SW_SHOW)
        
    END FUNCTION
    ' // END OF FILE
    Michael Mattias
    Tal Systems Inc. (retired)
    Racine WI USA
    [email protected]
    http://www.talsystems.com

  • #2
    Michael,
    What is this code supposed to be?
    Code:
        OSV.dwOsVersionInfoSize   =  SIZEOF(OSV)
        lRet                   &nbmage  GetVersionEx (OSV)
        IF ISTRUE lRet THEN
    Co,piling the sample program chokes on &nbmage with invalid numeric data error.
    Barry

    Comment


    • #3
      Something got garbled on the way to the forums, try this:
      Code:
          lRet      =  GetVersionEx (OSV)
      LarryC
      Website
      Sometimes life's a dream, sometimes it's a scream

      Comment


      • #4
        related info

        Info of possible interest to those on Win7:
        http://www.powerbasic.com/support/pb...ad.php?t=49883

        Comment


        • #5
          Code:
          'Made it compilable, some errors corrections, erratic tabulation realignment,
          'unneeded code removed, variables reformatted, etc.
          'Merged Main and Included files for more clarity.
          'Quickly done, will need to be revisited... :-)
           
          #COMPILE EXE '#Win 8.04#
          #DIM ALL
          #REGISTER NONE
          #INCLUDE "Win32Api.inc"
          'See PSAPI.inc
           
          TYPE PROCESS_MEMORY_COUNTERS DWORD
           cb                         AS DWORD
           PageFaultCount             AS DWORD
           PeakWorkingSetSize         AS DWORD
           WorkingSetSize             AS DWORD
           QuotaPeakPagedPoolUsage    AS DWORD
           QuotaPagedPoolUsage        AS DWORD
           QuotaPeakNonPagedPoolUsage AS DWORD
           QuotaNonPagedPoolUsage     AS DWORD
           PagefileUsage              AS DWORD
           PeakPagefileUsage          AS DWORD
          END TYPE
           
          DECLARE FUNCTION DynamicGetProcessMemoryInfo _ 'For dynamic call, needed if you plan to use on 9x Windows
          (BYVAL hProcess AS DWORD, ppsmemCounters AS PROCESS_MEMORY_COUNTERS, BYVAL cb AS DWORD) AS LONG
          '_____________________________________________________________________________
           
          FUNCTION StatToString(sStat AS PROCESS_MEMORY_COUNTERS) AS STRING
           
           FUNCTION = _
           "Page fault count"         & $TAB & $TAB & RSET$(FORMAT$(sStat.PageFaultCount, "0,"),             15) & $CRLF & _
           "Peak working set size"    & $TAB & $TAB & RSET$(FORMAT$(sStat.PeakWorkingSetSize, "0,"),         15) & $CRLF & _
           "Current working set size"        & $TAB & RSET$(FORMAT$(sStat.WorkingSetSize, "0,"),             15) & $CRLF & _
           "Quota peak paged pool Usage"     & $TAB & RSET$(FORMAT$(sStat.QuotaPeakPagedPoolUsage, "0,"),    15) & $CRLF & _
           "Quota paged pool usage"   & $TAB & $TAB & RSET$(FORMAT$(sStat.QuotaPagedPoolUsage, "0,"),        15) & $CRLF & _
           "Quota peak non paged pool usage" & $TAB & RSET$(FORMAT$(sStat.QuotaPeakNonPagedPoolUsage, "0,"), 15) & $CRLF & _
           "Quota non paged pool usage"      & $TAB & RSET$(FORMAT$(sStat.QuotaNonPagedPoolUsage, "0,"),     15) & $CRLF & _
           "Peak page fileUsage"      & $TAB & $TAB & RSET$(FORMAT$(sStat.PeakPageFileUsage, "0,"),          15) & $CRLF & _
           "Page file usage"   & $TAB & $TAB & $TAB & RSET$(FORMAT$(sStat.PageFileUsage, "0,"),              15) & $CRLF '& _
           
          END FUNCTION
          '_____________________________________________________________________________
           
          FUNCTION GetProcessMemoryStatistics(sBuffer AS STRING) AS LONG
           LOCAL ProcessMemory AS PROCESS_MEMORY_COUNTERS
           LOCAL zLibName      AS ASCIIZ * %MAX_PATH
           LOCAL zProcName     AS ASCIIZ * %MAX_PATH
           LOCAL hLIB          AS DWORD
           LOCAL hProcess      AS DWORD
           LOCAL pProc         AS DWORD
           LOCAL RetVal        AS LONG
           LOCAL cb            AS LONG
           
           hLib = LoadLibrary("PsApi.dll") 'Will be nothing on 9x. Need NT+
           IF hLIB THEN
             pProc = GetProcAddress(hLib, "GetProcessMemoryInfo")
             IF pProc THEN
               hProcess = GetCurrentProcess()
               cb       = SIZEOF(PROCESS_MEMORY_COUNTERS)
               CALL DWORD pProc USING DynamicGetProcessMemoryInfo (hPRocess, ProcessMemory,cb) TO RetVal
               IF RetVal THEN 'Succeeded
                  sBuffer = StatToString(ProcessMemory)
                  FUNCTION = %TRUE
               ELSE
                 sBuffer = "GetProcessMemoryInfoFailed"
               END IF
             ELSE
               sBuffer = "Can't Get Address for " & zProcName
             END IF
             FreeLibrary(hLib)
           ELSE
             sBuffer = "Can't load library, need NT+ " & zLibName
           END IF
           
          END FUNCTION
          '_____________________________________________________________________________
           
          FUNCTION PBMAIN () AS LONG
           LOCAL zFileName     AS ASCIIZ * %MAX_PATH
           LOCAL sMemStat      AS STRING
           LOCAL MemEater      AS STRING
           LOCAL CurrentPid    AS DWORD
           LOCAL hFile         AS DWORD
           LOCAL SuccessIfTrue AS LONG
           
           hFile     = FREEFILE
           zFileName = "Process_memory_Statistics.txt"
           OPEN zFileName FOR OUTPUT AS hFile
           CurrentPid = GetCurrentProcessId()
           PRINT #hFile, RIGHT$(DATE$, 4) & "-" & LEFT$(DATE$, 5) & "   " & TIME$ & $CRLF & _
                        "Process Memory Statistics for Process ID 0x" & _
                        HEX$(CurrentPid) & " (" & FORMAT$(CurrentPid) & ")"
           PRINT #hFile,
           MemEater = NUL$(1024 *1024 * 20)
           SuccessIfTrue = GetProcessMemoryStatistics(sMemStat)
           PRINT #hFile, "Process memory statistics with memory allocated"
           PRINT #hFile, sMemStat
           
           MemEater = NUL$(1)
           SuccessIfTrue = GetProcessMemoryStatistics(sMemStat)
           PRINT #hFile, "Process memory statistics with memory de-allocated"
           PRINT #hFile, sMemStat
           CLOSE hFile
           
           CurrentPid = ShellExecute(GetDesktopWindow, "open", zFileName, _
                                     BYVAL %NULL, BYVAL %NULL, %SW_SHOW)
           SLEEP 500 : KILL zFileName
           
          END FUNCTION
          '_____________________________________________________________________________
          '
          Last edited by Pierre Bellisle; 8 May 2016, 08:36 AM.

          Comment


          • #6
            Might want to fix the "Quota" field text descriptions in StatToString... gonna confuse people
            <b>George W. Bleck</b>
            <img src='http://www.blecktech.com/myemail.gif'>

            Comment


            • #7
              Done, this was a quick feedback.... :-D

              Pierre
              Last edited by Pierre Bellisle; 21 Mar 2016, 12:50 PM.

              Comment

              Working...
              X