Program Memory?
-
ozzie
- Enthusiast

- Posts: 443
- Joined: Sun Apr 06, 2008 12:54 pm
- Location: Brisbane, Qld, Australia
- Contact:
Program Memory?
Maybe I'm missing something obvious, but how can I find out, in my program, how much memory the program is using?
Re: Program Memory?
On windows I use the WorkingSetSize to determine RAM usage:
Code: Select all
EnableExplicit
Structure _PROCESS_MEMORY_COUNTERS
cb.l
PageFaultCount.l
PeakWorkingSetSize.i
WorkingSetSize.i
QuotaPeakPagedPoolUsage.i
QuotaPagedPoolUsage.i
QuotaPeakNonPagedPoolUsage.i
QuotaNonPagedPoolUsage.i
PagefileUsage.i
PeakPagefileUsage.i
EndStructure
Prototype pGetProcessMemoryInfo(a,b,c)
Procedure GetProcessWorkingSetSize(pid)
Protected ppsmemCounters._PROCESS_MEMORY_COUNTERS
Protected GetProcessMemoryInfo_.pGetProcessMemoryInfo
Protected hlib = OpenLibrary(#PB_Any, "Psapi.dll")
If hlib
GetProcessMemoryInfo_.pGetProcessMemoryInfo = GetFunction(hlib, "GetProcessMemoryInfo")
If GetProcessMemoryInfo_
GetProcessMemoryInfo_(pid, ppsmemCounters, SizeOf(_PROCESS_MEMORY_COUNTERS))
EndIf
CloseLibrary(hlib)
EndIf
ProcedureReturn ppsmemCounters\WorkingSetSize
EndProcedure
Debug GetProcessWorkingSetSize(GetCurrentProcess_())Re: Program Memory?
Can this be a way to work out the start/end addresses of a process' memory? To make a trainer for offline games?
- netmaestro
- PureBasic Bullfrog

- Posts: 8452
- Joined: Wed Jul 06, 2005 5:42 am
- Location: Fort Nelson, BC, Canada
Re: Program Memory?
I've done that before, though I used the _EX version of the structure and PrivateUsage, which seems most recommended through research. However, I can't find any member that will return anything close to the 1.1mb that Task Manager reports. For example, the posted code is returning nearly 6mb:
Code: Select all
EnableExplicit
Structure _PROCESS_MEMORY_COUNTERS_EX
cb.l
PageFaultCount.l
PeakWorkingSetSize.i
WorkingSetSize.i
QuotaPeakPagedPoolUsage.i
QuotaPagedPoolUsage.i
QuotaPeakNonPagedPoolUsage.i
QuotaNonPagedPoolUsage.i
PagefileUsage.i
PeakPagefileUsage.i
PrivateUsage.i
EndStructure
Prototype pGetProcessMemoryInfo(a,b,c)
Procedure GetProcessWorkingSetSize(pid)
Protected ppsmemCounters._PROCESS_MEMORY_COUNTERS_EX
Protected GetProcessMemoryInfo_.pGetProcessMemoryInfo
Protected hlib = OpenLibrary(#PB_Any, "Psapi.dll")
If hlib
GetProcessMemoryInfo_.pGetProcessMemoryInfo = GetFunction(hlib, "GetProcessMemoryInfo")
If GetProcessMemoryInfo_
GetProcessMemoryInfo_(pid, ppsmemCounters, SizeOf(_PROCESS_MEMORY_COUNTERS_EX))
EndIf
CloseLibrary(hlib)
EndIf
ProcedureReturn ppsmemCounters\WorkingSetSize
EndProcedure
OpenWindow(0,0,0,320,240,"",#PB_Window_SystemMenu|#PB_Window_ScreenCentered)
TextGadget(0, 10,10, 100, 20, Str( GetProcessWorkingSetSize(GetCurrentProcess_())))
Repeat:Until WaitWindowEvent()=#PB_Event_CloseWindow
BERESHEIT
Re: Program Memory?
Yeah, the TaskMgr has other memory stats available if you goto View - Select columns:
Commit Size(kB) = pmc\PrivateUsage / 1024
But Memory (Private working set) is found from a note I read somewhere else.
; Memory (Private working set):
; Not present in PROCESS_MEMORY_COUNTERS_EX
; Call QueryWorkingSet() to read all page entries into a buffer.
; Then count number of entries where PSAPI_WORKING_SET_INFORMATION::WorkingSetInfo[nI].Shared = 0.
; Multiply that by the bytes/page size (SYSTEM_INFO::dwPageSize)
; using GetSystemInfo() for total private working set (which is not the same as the committed private bytes PrivateUsage).
Commit Size(kB) = pmc\PrivateUsage / 1024
But Memory (Private working set) is found from a note I read somewhere else.
; Memory (Private working set):
; Not present in PROCESS_MEMORY_COUNTERS_EX
; Call QueryWorkingSet() to read all page entries into a buffer.
; Then count number of entries where PSAPI_WORKING_SET_INFORMATION::WorkingSetInfo[nI].Shared = 0.
; Multiply that by the bytes/page size (SYSTEM_INFO::dwPageSize)
; using GetSystemInfo() for total private working set (which is not the same as the committed private bytes PrivateUsage).
The nice thing about standards is there are so many to choose from. ~ Andrew Tanenbaum
Re: Program Memory?
"how can I find out, in my program, how much memory the program is using?"
Uhm, but what does it mean ?
Your program is not only the sum of the code and data sections and the stack and the resources allocated on the heap.
It uses DLL loaded from the OS to call the API, it uses system resources like kernel objects, gdi objects, etc., some of this stuff MAY BE shared between process, some is not, and most is allocated outside your process address space but still requires RAM and it's there only because your process exists. Actually many objects managed by the OS have two parts, a user mode and a kernel mode part, this because for example GDI need some data in kernel mode to access it quickly when it's drawing, but you need some data in user mode if you need the change an attribute. So how much memory is used by your program ?
The smaller number you see in the TM I suppose is the private one.
I don't know of an API to get that (someone knows?), TM itself get most of its data from performance counters so you could probably get that info the same way, or the hard way by using the API QueryWorkingSet() -> https://msdn.microsoft.com/en-us/librar ... 85%29.aspx (mentioned also by Skywalk, I just noticed that) and inspect the field shared/private for the array of pages returned and filter out the ones you want.
Anyway, here is one example -> http://www.codeproject.com/Articles/875 ... grammatica
Uhm, but what does it mean ?
Your program is not only the sum of the code and data sections and the stack and the resources allocated on the heap.
It uses DLL loaded from the OS to call the API, it uses system resources like kernel objects, gdi objects, etc., some of this stuff MAY BE shared between process, some is not, and most is allocated outside your process address space but still requires RAM and it's there only because your process exists. Actually many objects managed by the OS have two parts, a user mode and a kernel mode part, this because for example GDI need some data in kernel mode to access it quickly when it's drawing, but you need some data in user mode if you need the change an attribute. So how much memory is used by your program ?
The working set is splitted in two parts, private and shared, the number you get with your code should be the sum of the two.netmaestro wrote:However, I can't find any member that will return anything close to the 1.1mb that Task Manager reports. For example, the posted code is returning nearly 6mb:
The smaller number you see in the TM I suppose is the private one.
I don't know of an API to get that (someone knows?), TM itself get most of its data from performance counters so you could probably get that info the same way, or the hard way by using the API QueryWorkingSet() -> https://msdn.microsoft.com/en-us/librar ... 85%29.aspx (mentioned also by Skywalk, I just noticed that) and inspect the field shared/private for the array of pages returned and filter out the ones you want.
Anyway, here is one example -> http://www.codeproject.com/Articles/875 ... grammatica
"Have you tried turning it off and on again ?"
-
ozzie
- Enthusiast

- Posts: 443
- Joined: Sun Apr 06, 2008 12:54 pm
- Location: Brisbane, Qld, Australia
- Contact:
Re: Program Memory?
The background to this request is that my software uses the BASS audio library and one of my users sometimes gets an 'out of memory' error returned by BASS when the program tries to open an audio file. When this does occur, it is not immediately - the program can play many files successfully before this 'out of memory' error occurs. So I thought if I could regularly monitor the amount of memory used by the program it would help ascertain if the memory usage is constantly growing, which probably indicates I'm not freeing up files and/or memory when I should be.luis wrote:"how can I find out, in my program, how much memory the program is using?"
Uhm, but what does it mean ?
I'll try monitoring the WorkingSetSize and see if that helps.
Re: Program Memory?
In that case take a look to EmptyWorkingSet() too, could be useful to call that before you check the size to see if it's really growing, else unless the leak is very big could be difficult to compare values. Especially if your user switch programs or minimize/maximize yours (the last operation causes the working set to be compacted).
Maybe this thread can also contain some useful suggestions ?
http://www.purebasic.fr/english/viewtop ... 13&t=56737
Maybe this thread can also contain some useful suggestions ?
http://www.purebasic.fr/english/viewtop ... 13&t=56737
"Have you tried turning it off and on again ?"
-
ozzie
- Enthusiast

- Posts: 443
- Joined: Sun Apr 06, 2008 12:54 pm
- Location: Brisbane, Qld, Australia
- Contact:
Re: Program Memory?
Thanks everyone for the useful info. It appears there is some memory leakage in my program which I'll need to investigate.
Re: Program Memory?
No.Dude wrote:Can this be a way to work out the start/end addresses of a process' memory? To make a trainer for offline games?
It doesnt work like this, it's much easier. There is no "process starting address" memory managment does not work this way. However you can just use the API functions ReadProcessMemory and WriteProcessMemory to access the memory of another process.
Re: Program Memory?
But how do I find a value in the process memory? Say I need to search for 100, then 99, then 98. I need to know where to start searching and where to stop. Can you provide any theory so I can work out the practice?Thorium wrote:you can just use the API functions ReadProcessMemory and WriteProcessMemory to access the memory of another process.
Re: Program Memory?
You can find some examples if you search for "trainer" on the forums. For example this: http://www.purebasic.fr/english/viewtop ... 12&t=44754Dude wrote:But how do I find a value in the process memory? Say I need to search for 100, then 99, then 98. I need to know where to start searching and where to stop. Can you provide any theory so I can work out the practice?Thorium wrote:you can just use the API functions ReadProcessMemory and WriteProcessMemory to access the memory of another process.
The theory is that you can use VirtualQueryEx to enumerate all memory regions which are allocated in the target process and read them with ReadProcessMemory. You can then perform a binary search on the region you read.
You have to understand that every process has it's own virtual address space. That means you can't just access for example address $1000 with a peek operation. The peek operation will access $1000 in the address space of your own process. If you use ReadProcessMemory you specify the process you want to read address $1000 from.
How it's stored in physical memory is the responsibility of the operating system. It will map the virtual addresses to physical addresses and offsets in the swap file or even directly to files on the hard disc. That enables the operating system to optimize memory usage for example by physicaly loading a dll only one time that is loaded in many process address spaces. All virtual addresses of that dll will map to the same addresses in physical memory until a process changes the memory content.
