How can I find out how much of address space the application is consuming and report this to user? - winapi

I'm writing the memory manager for an application, as part of a team of twenty-odd coders. We're running out of memory quota and we need to be able to see what's going on, since we only appear to be using about 700Mb. I need to be able to report where it's all going - fragmentation etc. Any ideas?

You can use existing memory debugging tools for this, I found Memory Validator 1 quite useful, it is able to track both API level (heap, new...) and OS level (Virtual Memory) allocations and show virtual memory maps.
The other option which I also found very usefull is to be able to dump a map of the whole virtual space based on VirtualQuery function. My code for this looks like this:
void PrintVMMap()
{
size_t start = 0;
// TODO: make portable - not compatible with /3GB, 64b OS or 64b app
size_t end = 1U<<31; // map 32b user space only - kernel space not accessible
SYSTEM_INFO si;
GetSystemInfo(&si);
size_t pageSize = si.dwPageSize;
size_t longestFreeApp = 0;
int index=0;
for (size_t addr = start; addr<end; )
{
MEMORY_BASIC_INFORMATION buffer;
SIZE_T retSize = VirtualQuery((void *)addr,&buffer,sizeof(buffer));
if (retSize==sizeof(buffer) && buffer.RegionSize>0)
{
// dump information about this region
printf(.... some buffer information here ....);
// track longest feee region - usefull fragmentation indicator
if (buffer.State&MEM_FREE)
{
if (buffer.RegionSize>longestFreeApp) longestFreeApp = buffer.RegionSize;
}
addr += buffer.RegionSize;
index+= buffer.RegionSize/pageSize;
}
else
{
// always proceed
addr += pageSize;
index++;
}
}
printf("Longest free VM region: %d",longestFreeApp);
}

You can also find out information about the heaps in a process with Heap32ListFirst/Heap32ListNext, and about loaded modules with Module32First/Module32Next, from the Tool Help API.
'Tool Help' originated on Windows 9x. The original process information API on Windows NT was PSAPI, which offers functions which partially (but not completely) overlap with Tool Help.

Our (huge) application (a Win32 game) started throwing "Not enough quota" exceptions recently, and I was charged with finding out where all the memory was going. It is not a trivial job - this question and this one were my first attempts at finding out. Heap behaviour is unexpected, and accurately tracking how much quota you've used and how much is available has so far proved impossible. In fact, it's not particularly useful information anyway - "quota" and "somewhere to put things" are subtly and annoyingly different concepts. The accepted answer is as good as it gets, although enumerating heaps and modules is also handy. I used DebugDiag from MS to view the true horror of the situation, and understand how hard it is to actually thoroughly track everything.

Related

invalid number specified with option "/HEAP:1[,10]"

My Malloc is failing in my project.
Malloc runs several times via a one of the functions but fails due to lack of memory.
I am trying to increase the heap size in my VC++ but it gives me the error as above in the subject.
Can someone please tell me what is wrong in this ?
Windows server 2003 R2 Enterprise edition
And i am using VC++ 98 edition.
I tried some search but could not get anything conclusive on how to use /HEAP OPTION.
should the numbers be in MB ?
message_t* Allocate_momory(MsgType_t msgType, UInt16 dataLength)
{
// TO DO: Allocate memenory and return the pointer
message_t* mes_t;
mes_t = (message_t*) malloc(sizeof (message_t));
mes_t->msgType = msgType;
mes_t->dataLength = 0;
mes_t->clientID = 0;
mes_t->usageCount = 0;
mes_t->dataBuf = malloc(sizeof (dataLength));
return mes_t;
}
Yes it worked... But it unfortunatly did not solve my problem with malloc :( !!
This is a huge project with too many files.
I can't post the code but can someone guide me how should i try to debug a problem where malloc is failing ?
/HEAP sets the heap size in bytes. Also the square brackets in the documentation denote an optional parameter - you don't actually type these in. So it would be e.g.
/HEAP:1073741824
for a 1 GB heap, or
/HEAP:1073741824,16777216
if you really do want to specify the "commit" parameter in addition to the heap size (you probably don't).
Unfortunately I don't think this will solve your real problem, which is that you are running out of memory. You may have memory leaks, which you can track down with a tool such as valgrind. If that's not the case then you have a bad design, which will be a lot harder to fix than memory leaks.

getloadavg() within kernel

Is there an equivalent api like getloadavg() that can be used within the kernel i.e. for my own driver ?
I have a driver that is thrashing and I would like to throttle it, and i am looking for a kernel-api to find about the cpu usage.
Thank you.
You're probably looking for the get_avenrun() function in kernel/sched.c. An example of how to use it is in fs/proc/loadavg.c:
static int loadavg_proc_show(struct seq_file *m, void *v)
{
unsigned long avnrun[3];
get_avenrun(avnrun, FIXED_1/200, 0);
seq_printf(m, "%lu.%02lu %lu.%02lu %lu.%02lu %ld/%d %d\n",
LOAD_INT(avnrun[0]), LOAD_FRAC(avnrun[0]),
LOAD_INT(avnrun[1]), LOAD_FRAC(avnrun[1]),
LOAD_INT(avnrun[2]), LOAD_FRAC(avnrun[2]),
nr_running(), nr_threads,
task_active_pid_ns(current)->last_pid);
return 0;
}
Though I'm a little skeptical of how you can use the load average to modify a driver -- the load average is best treated as a heuristic for system administrators to gauge how their system changes over time, not necessarily how "healthy" it might be at any given moment -- what specifically in the driver is causing troubles? There's probably a better mechanism to make it play nicely with the rest of the system.

How to know what amount of memory I'm using in a process? win32 C++

I'm using
Win32 C++ in
CodeGear Builder 2009
Target is Windows XP Embedded.
I found the PROCESS_MEMORY_COUNTERS_EX struct
and I have created a siple function to return the
Memory consumption of my process
SIZE_T TForm1::ProcessPrivatBytes( DWORD processID )
{
SIZE_T lRetval = 0;
HANDLE hProcess;
PROCESS_MEMORY_COUNTERS_EX pmc;
hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ,
FALSE, processID );
if (NULL == hProcess)
{
lRetval = 1;
}
else
{
if ( GetProcessMemoryInfo( hProcess, (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc)) )
{
lRetval = pmc.WorkingSetSize;
lRetval = pmc.PrivateUsage;
}
CloseHandle( hProcess );
}
return lRetval;
}
//---------------------------------------------------------------------------
Do i have to use lRetval = pmc.WorkingSetSize; or lRetval = pmc.PrivateUsage;
the privateUsage are what I see in perfmon.
but what is that WorkingSetSize exactly.
I what to see every byte I allocate in the counter when I allocate it. Is this Posible?
regards
jvdn
This is a much tougher question than you probably realized. The reason is that Windows shares most executable code between processes (especially the ones that make up most of Windows itself) between processes. For example, there's normally ONE copy of kernel32.dll loaded into memory, but it'll normally be mapped into every process. Do you consider that part of the memory your process is "using" or not?
Private memory is what's unique to that particular process. This can be somewhat misleading too. Since the executable for your process could potentially be shared with another process (i.e. two instances of your program could be run), that's not counted as part of the private memory, even if (as is often the case) there's only one instance of it running.
The working set size is about 99.999% meaningless. What it returns is whatever has been set as the preferred working set size for the process. You can adjust that with SetProcessWorkingSetSize(). Windows has a working set trimmer that attempts to trim down working sets. If memory serves, it uses the working set size to guess at whether it's worth trying to trim the working set of this process -- i.e. if its current working set is larger than the working set size was set to, it tries to trim it down. Otherwise, it (mostly) leaves it alone.
Chances are that nothing you do will show you ever byte you allocate as you allocate it though. Calling Windows to allocate memory is fairly slow, so what's normally done is that the run-time library allocates a fairly big chunk of memory from Windows. When you allocate memory, the run-time library gives you a piece of that big chunk. Only when that chunk is gone does it go back to Windows and ask for more.

Unmanaged VC++ Application's memory consumption on windows server

OK, so I have a very large multi-threaded unmanaged c++ application (server) that runs on a windows 2003 server. It hosts sessions for 20-50 concurrent users doing all sorts of business logic... At times it can be using a very large amount of memory due to things like object/session caching due to users having large numbers of windows open in the clients (each window has a separate server 'session'.
We routinely see consumption of more than 5-600 MB physical memory and 5-600 MB of virtual memory. Once it gets to this point we seem to start having 'out of memory' errors.
Now I know that Windows will start page-faulting when it feels it needs to free up physical memory, and also that win32 applications normally are only able to allocate up to a maximum of 4GB worth of memory, really only with 2GB of that available for actual use by the application for 'user-mode' address space, and even less of that after other libraries are loaded... I'm not sure if the 'user-mode' memory usage is what is reported on the Task Manager...
So anyway my real question is:
How can I find out how much user-mode memory my application has access to, and how much has been used at any given time (preferably from outside of the application, i.e. some windows management tool)?
[edit] After looking at the Process Explorer and the website, it looks like the value 'Virtual Size' is the value of how much memory the application has access to.
Sounds like a case for Process Explorer, a free utility from Microsoft SysInternals:
(source: microsoft.com)
Description:
Ever wondered which program has a
particular file or directory open? Now
you can find out. Process Explorer
shows you information about which
handles and DLLs processes have opened
or loaded.
The Process Explorer display consists
of two sub-windows. The top window
always shows a list of the currently
active processes, including the names
of their owning accounts, whereas the
information displayed in the bottom
window depends on the mode that
Process Explorer is in: if it is in
handle mode you'll see the handles
that the process selected in the top
window has opened; if Process Explorer
is in DLL mode you'll see the DLLs and
memory-mapped files that the process
has loaded. Process Explorer also has
a powerful search capability that will
quickly show you which processes have
particular handles opened or DLLs
loaded.
The unique capabilities of Process
Explorer make it useful for tracking
down DLL-version problems or handle
leaks, and provide insight into the
way Windows and applications work.
If you are looking for more info in terms of terminal-server specific info, I've been following the blog of a programmer that is releasing a beta of a tool that I believe will fit your needs perfectly. It is an improved TSAdmin. He calls it TSAdminEx.
See below for a screenshot, and click here to learn more about it and to get the beta. It's free software, BTW.
I know you asked for preferably from outside of the application, but I was googling for how to find such information from within my own program and stumbled upon your post. So, this is to benefit people who want this information from within their program.
unmanaged C++
#include <windows.h>
#include <stdio.h>
#include <psapi.h>
void PrintMemoryInfo( DWORD processID )
{
HANDLE hProcess;
PROCESS_MEMORY_COUNTERS pmc;
// Print the process identifier.
printf( "\nProcess ID: %u\n", processID );
// Print information about the memory usage of the process.
hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ,
FALSE,
processID );
if (NULL == hProcess)
return;
if ( GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc)) )
{
printf( "\tPageFaultCount: 0x%08X\n", pmc.PageFaultCount );
printf( "\tYour app's PEAK MEMORY CONSUMPTION: 0x%08X\n",
pmc.PeakWorkingSetSize );
printf( "\tYour app's CURRENT MEMORY CONSUMPTION: 0x%08X\n", pmc.WorkingSetSize );
printf( "\tQuotaPeakPagedPoolUsage: 0x%08X\n",
pmc.QuotaPeakPagedPoolUsage );
printf( "\tQuotaPagedPoolUsage: 0x%08X\n",
pmc.QuotaPagedPoolUsage );
printf( "\tQuotaPeakNonPagedPoolUsage: 0x%08X\n",
pmc.QuotaPeakNonPagedPoolUsage );
printf( "\tQuotaNonPagedPoolUsage: 0x%08X\n",
pmc.QuotaNonPagedPoolUsage );
printf( "\tPagefileUsage: 0x%08X\n", pmc.PagefileUsage );
printf( "\tPeakPagefileUsage: 0x%08X\n",
pmc.PeakPagefileUsage );
}
CloseHandle( hProcess );
}
int main( )
{
PrintMemoryInfo( GetCurrentProcessId() );
return 0;
}
You wrote:
When your talking how much memory a
win32 app can access they specifically
call it 'user-mode' memory which I
don't see as an option or at least I
don't know what column it really is.
Have a look at this article (written by the creator of Process Explorer, Dr. Mark Russinovich).
To be able to manage your Windows systems effectively you need to understand how Windows manages physical resources, such as CPUs and memory, as well as logical resources, such as virtual memory, handles, and window manager objects. Knowing the limits of those resources and how to track their usage enables you to attribute resource usage to the applications that consume them, effectively size a system for a particular workload, and identify applications that leak resources.

Do memory deallocation routines touch the block being freed?

Windows HeapFree, msvcrt free: do they cause the memory being freed to be paged-in? I am trying to estimate if not freeing memory at exit would speed up application shutdown significantly.
NOTE: This is a very specific technical question. It's not about whether applications should or should not call free at exit.
If you don't cleanly deallocate all your resources at application shutdown it will make it nigh on impossible to detect if you have any really serious problems - like memory leaks - which would be more of a problem than a slow shut down. If the UI disappears quickly, then the user will think the it has shut down quickly even if it has a lot of work still to do. With UI, perception of speed is more important than actual speed. When the user selects the 'Exit Application' option, the main application window should immediately disappear. It doesn't matter if the application takes a few seconds after that to free up everything an exit gracefully, the user won't notice.
I ran a test for HeapFree. The following program has access violation inside HeapFree at i = 31999:
#include <windows.h>
int main() {
HANDLE heap = GetProcessHeap();
void * bufs[64000];
// populate heap
for (unsigned i = 0; i < _countof(bufs); ++i) {
bufs[i] = HeapAlloc(heap, 0, 4000);
}
// protect a block in the "middle"
DWORD dwOldProtect;
VirtualProtect(
bufs[_countof(bufs) / 2], 4000, PAGE_NOACCESS,
&dwOldProtect);
// free blocks
for (unsigned i = 0; i < _countof(bufs); ++i) {
HeapFree(heap, 0, bufs[i]);
}
}
The stack is
ntdll.dll!_RtlpCoalesceFreeBlocks#16() + 0x12b9 bytes
ntdll.dll!_RtlFreeHeap#12() + 0x91f bytes
shutfree.exe!main() Line 19 C++
So it looks like the answer is "Yes" (this applies to free as well, since it uses HeapFree internally)
I'm almost certain the answer to the speed improvement question would be "yes". Freeing a block may or may not touch the actual block in question, but it will certainly have to update other bookkeeping information in any case. If you have zillions of small objects allocated (it happens), then the effort required to free them all could have a significant impact.
If you can arrange it, you might try setting up your application such that if it knows it's going to quit, save any pending work (configuration, documents, whatever) and exit ungracefully.

Resources