This program retrieves the value shown in Task Manager under the "Memory (Private Working Set)" column in Windows Vista/Windows 7 (and, presumably, above) -- this is effectively the actual memory currently in use by a program. (You may have to enable this column in the View -> Select Columns menu.)
To try it, scroll to the bottom of the code and set 'pid' to a value in Task Manager's PID column, then check against Memory (Private Working Set)...
Code: Select all
; Based on method posted by Najam ul Hassan at:
;
; http://www.codeproject.com/Articles/87529/Calculate-Memory-Working-Set-Private-Programmatica
; Process ID from Task Manager -- compare to Memory (Private Working Set) column:
pid.i = x ; CHANGE ME! See above...
If pid = 0
MessageRequester ("Error!", "Change pid in source!", #MB_ICONWARNING)
End
EndIf
Structure PSAPI_WORKING_SET_BLOCK
Flags.i
EndStructure
Structure PSAPI_WORKING_SET_INFORMATION
NumberOfEntries.i
WorkingSetInfo.PSAPI_WORKING_SET_BLOCK [1]
EndStructure
GetSystemInfo_ (si.SYSTEM_INFO)
page_size.i = si\dwPageSize
Dim wsi.PSAPI_WORKING_SET_INFORMATION (0)
psapi.i = OpenLibrary (#PB_Any, "psapi.dll")
If psapi
*QueryWorkingSet = GetFunction (psapi, "QueryWorkingSet")
If *QueryWorkingSet
phandle.i = OpenProcess_ (#PROCESS_QUERY_INFORMATION | #PROCESS_VM_READ, #False, pid)
If phandle
; Fill in a PSAPI_WORKING_SET_INFORMATION Structure...
result.i = CallFunctionFast (*QueryWorkingSet, phandle, @wsi (0), SizeOf (PSAPI_WORKING_SET_INFORMATION))
If result = 0
If GetLastError_ () = #ERROR_BAD_LENGTH
; Get number of entries from PSAPI_WORKING_SET_INFORMATION and
; create an array of PSAPI_WORKING_SET_BLOCKs...
Dim wsb.PSAPI_WORKING_SET_BLOCK (wsi (0)\NumberOfEntries)
; Stupid Dim uses elements - 1 to define size of array. Therefore above
; includes NumberOfEntries + 1 elements. Luckily, we need element (0) to
; take what would be wsi (0)\NumberOfEntries if actually filling in a
; PSAPI_WORKING_SET_INFORMATION structure...
wsb_size.i = ArraySize (wsb ()) + 1 ; Handling stupid PB array size crap!
wsb_size = wsb_size * SizeOf (PSAPI_WORKING_SET_BLOCK)
result.i = CallFunctionFast (*QueryWorkingSet, phandle, @wsb (), wsb_size)
If result
; Note: wsb (0) is basically wsi (0)\NumberOfEntries,
; so let's ditch it! Shift all elements back one...
For loop.i = 0 To ArraySize (wsb ()) - 1
wsb (loop) = wsb (loop + 1)
Next
; Drop last element...
ReDim wsb (ArraySize (wsb ()) - 1)
; Sort into page order (or something, um, yeah)...
SortStructuredArray (wsb (), #PB_Sort_Ascending, OffsetOf (PSAPI_WORKING_SET_BLOCK\Flags), #PB_Long)
pages.i = wsi (0)\NumberOfEntries
shared_pages.i = 0
For loop.i = 0 To pages - 1 ; NumberOfEntries
page_status.i = 0
page_address.i = wsb (loop)\Flags & $FFFFF000
page_flags.i = wsb (loop)\Flags & $00000FFF
While loop < pages
page_status = page_status + 1
If loop = pages - 1
Break
EndIf
this_page_address.i = wsb (loop)\Flags & $FFFFF000
next_page_address.i = wsb (loop + 1)\Flags & $FFFFF000
next_page_flags.i = wsb (loop + 1)\Flags & $00000FFF
If ((this_page_address + page_size) = next_page_address) And (page_flags = next_page_flags)
loop = loop + 1
Else
Break
EndIf
Wend
If page_address < $C0000000 Or page_address > $E0000000
If page_flags & $100
shared_pages = shared_pages + page_status
EndIf
EndIf
Next
total_pages.i = pages * 4
shared_pages = shared_pages * 4
private_kb.i = total_pages - shared_pages
Debug "Private: " + Str (private_kb) + " K"
Else
Debug "Problem with working set array size"
EndIf
Else
Debug "Unknown error obtaining working set"
EndIf
EndIf
CloseHandle_ (phandle)
EndIf
EndIf
CloseLibrary (psapi)
EndIf
Code: Select all
If page_address < $C0000000 Or page_address > $E0000000