Page 1 of 1
Program Memory?
Posted: Mon Mar 23, 2015 2:28 am
by ozzie
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?
Posted: Mon Mar 23, 2015 9:41 am
by PureGuy
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?
Posted: Mon Mar 23, 2015 11:47 am
by Dude
Can this be a way to work out the start/end addresses of a process' memory? To make a trainer for offline games?
Re: Program Memory?
Posted: Mon Mar 23, 2015 8:07 pm
by netmaestro
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
Re: Program Memory?
Posted: Mon Mar 23, 2015 8:37 pm
by skywalk
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).
Re: Program Memory?
Posted: Mon Mar 23, 2015 10:08 pm
by luis
"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 ?
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 working set is splitted in two parts, private and shared, the number you get with your code should be the sum of the two.
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
Re: Program Memory?
Posted: Tue Mar 24, 2015 1:21 am
by ozzie
luis wrote:"how can I find out, in my program, how much memory the program is using?"
Uhm, but what does it mean ?
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.
I'll try monitoring the WorkingSetSize and see if that helps.
Re: Program Memory?
Posted: Tue Mar 24, 2015 1:36 am
by luis
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
Re: Program Memory?
Posted: Tue Mar 24, 2015 9:00 am
by ozzie
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?
Posted: Tue Mar 24, 2015 9:51 am
by Thorium
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?
No.
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?
Posted: Tue Mar 24, 2015 12:26 pm
by Dude
Thorium wrote:you can just use the API functions ReadProcessMemory and WriteProcessMemory to access the memory of another process.
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?
Re: Program Memory?
Posted: Tue Mar 24, 2015 1:00 pm
by Thorium
Dude wrote:Thorium wrote:you can just use the API functions ReadProcessMemory and WriteProcessMemory to access the memory of another process.
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?
You can find some examples if you search for "trainer" on the forums. For example this:
http://www.purebasic.fr/english/viewtop ... 12&t=44754
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.