Virtual Size and GlobalMemoryStatusEx - windows

My system is Windows XP.
Virtual Size displayed in TaskManager is different with MEMORYSTATUSEX.ullAvailVirtual got from GlobalMemoryStatusEx.
When I create lot of buffers and the memory usage is up, MEMORYSTATUSEX.ullAvailVirtual can well reflected the virtual size usage. It's same.
But when I delete the memory, Virtual Size in task manager is down, but MEMORYSTATUSEX.ullAvailVirtual is still very small. I don't know why....
I am totally confused.

You could be suffering from memory fragmentation. (I.e. if you lea a few bytes between each large allocation, it effectively forces up the virtual bytes of your application).
You might find it more reliable to compare figures against perfmon - the counters I've always used in the past have been Private bytes (memory actually allocated) and Virtual bytes (memory address space allocated) - if those two counters diverge, then you have a memory fragmentation problem, which will be the result of a memory leak. The figures in Task Manager, whilst true and accurate, don't convey anything particularly useful.

When you delete allocated memory, the OS doesn't immediately return that memory but keeps it reserved for the process, at least until another process needs that memory. This improves the performance, because the very same process might need the just deleted memory a few ms later again.
To really free the deleted memory, you can call
SetProcessWorkingSetSize(GetCurrentProcess(), (SIZE_T)-1, (SIZE_T)-1);
Maybe that will force GlobalMemoryStatusEx() to return the values you expect?

Related

Will Windows be still able to allocate memory when free space in physical memory is very low?

On Windows 32-bit system the application is being developed using Visual Studio:
Lets say lots of other application running on my machine and they have occupied almost all of physical memory and only 1 MB memory is left free. If my application (which has not yet allocated any memory) tries to allocate, say 2 MB, will the call be successful?
My guess: In theory, each Windows application has 2GB of virtual memory available.
So I believe this call should be successful (regardless how much physical memory is available). But I am not sure on this. That's why asking here.
Windows gives a rock-hard guarantee that this will always work. A process can only allocate virtual memory when Windows can commit space in the paging file for the allocation. If necessary, it will grow the paging file to make the space available. If that fails, for example when the paging file grows beyond the preset limit, then the allocation fails as well. Windows doesn't have the equivalent of the Linux "OOM killer", it does not support over-committing that may require an operating system to start randomly killing processes to find RAM.
Do note that the "always works" clause does have a sting. There is no guarantee on how long this will take. In very extreme circumstances the machine can start thrashing where just about every memory access in the running processes causes a page fault. Code execution slows down to a crawl, you can lose control with the mouse pointer frozen when Explorer or the mouse or video driver start thrashing as well. You are well past the point of shopping for RAM when that happens. Windows applies quotas to processes to prevent them from hogging the machine, but if you have enough processes running then that doesn't necessarily avoid the problem.
Of course. It would be lousy design if memory had to be wasted now in order to be used later. Operating systems constantly re-purpose memory to its most advantageous use at any moment. They don't have to waste memory by keeping it free just so that it can be used later.
This is one of the benefits of virtual memory with a page file. Because the memory is virtual, the system can allocate more virtual memory than physical memory. Virtual memory that cannot fit in physical memory, is pushed out to the page file.
So the fact that your system may be using all of the physical memory does not mean that your program will not be able to allocate memory. In the scenario that you describe, your 2MB memory allocation will succeed. If you then access that memory, the virtual memory will be paged in to physical memory and very likely some other pages (maybe in your process, maybe in another process) will be pushed out to the page file.
Well, it will succeed as long as there's some memory for it - apart from physical memory, there's also the page file.
However, once you reach the limit of both RAM and the page file, you're done for and that's when the out of memory situation really starts being fun.
Now, systems like Windows Vista will try to use all of your available RAM, pretty much for caching. That's a good thing, and when there's a request for memory from an application, the cache will be thrown away as needed.
As for virtual memory, you can request much more than you have available, regardless of your RAM or page file size. Only when you commit the memory does it actually need some backing - either RAM or the page file. On 64-bit, you can easily request terabytes of virtual memory - that doesn't mean you'll get it when you try to commit it, though :P
If your application is unable to allocate a physical memory (RAM) block to store information, the operating system takes over and 'pages' or stores sections that are in RAM on disk to free up physical memory so that your program is able to perform the allocation. This is done automatically and is completely invisible to your applications.
So, in your example, on a system that has 1MB RAM free, if your application tries to allocate memory, the operating system will page certain contents of physical memory to disk and free up RAM for your application. Your application will not crash in this case.
This, obviously is much more complicated than that.
There are several ways to configure a page file on Windows (fixed size, variable size and on which disk). If you run out of physical memory, and out of hard drive space (because your page file has grown very large due to excessive 'paging') or reach the limit of your paging file (if it is a static limit) then your applications will fail due out an out-of-memory exception. With today's systems with large local storage however, this is a rare event.
Be sure to read about paging for the full picture. Check out:
http://en.wikipedia.org/wiki/Paging
In certain cases, you will notice that you have sufficient free physical memory. Say 100MB and your program tries to allocate a 10MB block to store a large object but fails. This is caused by physical memory fragmentation. Although the total free memory is 100MB, there is no single contiguous block of 10MB that can be used to store your object. This will result in an exception that needs to be handled in your code. If you allocate large objects in your code you may want to separate the allocation into smaller blocks to facilitate allocation, and then aggregate them back in your code logic. For example, instead of having a single 10m vector, you can declare 10 x 1m vectors in an array and allocate memory for each individual one.

What's all this uncommitted, reserved memory in my process?

I'm using VMMap from SysInternals to look at memory allocated by my Win32 C++ process on WinXP, and I see a bunch of allocations where portions of the allocated memory are reserved but not committed. As far as I can tell, from my reading and testing, all of the common memory allocators (e.g., malloc, new, LocalAlloc, GlobalAlloc) used in a C++ program always allocate fully committed blocks of memory.
Heaps are a common example of code that reserves memory but doesn't commit it until needed. I suspect that some of these blocks are Windows/CRT heaps, but there appears to be more of these types of blocks than I would expect for heaps. I see on the order of 30 of these blocks in my process, between 64k and 8MB in size, and I know that my code never intentionally calls VirtualAlloc to allocate reserved, uncommitted memory.
Here are a couple of examples from VMMap: http://www.flickr.com/photos/95123032#N00/5280550393/
What else would allocate such blocks of memory, where much of it is reserved but not committed? Would it make sense that my process has 30 heaps? Thanks.
I figured it out - it's the CRT heap that gets allocated by calls to malloc. If you allocate a large chunk of memory (e.g., 2 MB) using malloc, it allocates a single committed block of memory. But if you allocate smaller chunks (say 177kb), then it will reserve a 1 MB chunk of memory, but only commit approximately what you asked for (e.g., 184kb for my 177kb request).
When you free that small chunk, that larger 1 MB chunk is not returned to the OS. Everything but 4k is uncommitted, but the full 1 MB is still reserved. If you then call malloc again, it will attempt to use that 1 MB chunk to satisfy your request. If it can't satisfy your request with the memory that it's already reserved, it will allocate a new chunk of memory that's twice the previous allocation (in my case it went from 1 MB to 2 MB). I'm not sure if this pattern of doubling continues or not.
To actually return your freed memory to the OS, you can call _heapmin. I would think that this would make a future large allocation more likely to succeed, but it would all depend on memory fragmentation, and perhaps heapmin already gets called if an allocation fails (?), I'm not sure. There would also be a performance hit since heapmin would release the memory (taking time) and malloc would then need to re-allocate it from the OS when needed again. This information is for Windows/32 XP, your mileage may vary.
UPDATE: In my testing, heapmin did absolutely nothing. And the malloc heap is only used for blocks that are less than 512kb. Even if there are MBs of contiguous free space in the malloc heap, it will not use it for requests over 512kb. In my case, this freed, unused, yet reserved malloc memory chewed up huge parts of my process' 2GB address space, eventually leading to memory allocation failures. And since heapmin doesn't return the memory to the OS, I haven't found any solution to this problem, other than restarting my process or writing my own memory manager.
Whenever a thread is created in your application a certain (configurable) amount of memory will be reserved in the address space for the call stack of the thread. There's no need to commit all the reserved memory unless your thread is actually going to need all of that memory. So only a portion needs to be committed.
If more than the committed amount of memory is required, it will be possible to obtain more system memory.
The practical consideration is that the reserved memory is a hard limit on the stack size that reduces address space available to the application. However, by only committing a portion of the reserve, we don't have to consume the same amount of memory from the system until needed.
Therefore it is possible for each thread to have a portion of reserved uncommitted memory. I'm unsure what the page type will be in those cases.
Could they be the DLLs loaded into your process? DLLs (and the executable) are memory mapped into the process address space. I believe this initially just reserves space. The space is backed by the files themselves (at least initially) rather than the pagefile.
Only the code that's actually touched gets paged in. If I understand the terminology correctly, that's when it's committed.
You could confirm this by running your application in a debugger and looking at the modules that are loaded and comparing their locations and sizes to what you see in VMMap.

Real Memory VS. Private Memory

I have an Objective-C application that is designed to run for an extended period of time using WebKit views. After time the application builds up a fair amount of memory so I would like to accurately reveal the memory usage to the end user upon request. In Activity Monitor on OS X I see two memory values for my application Real Memory and Private Memory. From what I have read Private is everything that the process has and Real is an estimate. What should I trust? Is there a specific formula I can use to calculate the exact usage rather than what OS X reports?
Not my area of expertise.
If you are worried about memory leaks, you should be using the various tools provided by Apple to debug it.
Real memory is the actual physical memory in use by the process.
Private memory is the physical memory that is used by just that process.
Virtual memory is the size of the entire virtual memory of the process including those pages that are not currently resident in physical RAM.
It's actually quite difficult to tell by looking at those numbers if you have a leak. For example, a block that is malloced and then leaked will never be referenced again, so it'll eventually get swapped out. It'll be part of the virtual memory but not part of the resident memory. So if you have a leak, the virtual memory will gradually increase over time.
On the other hand, virtual memory will increase if malloc can't find an unused block of memory to allocate, but it won't decrease when free gives memory back. So if you malloc a huge amount of RAM the VM will increase but even if you then free it correctly, it'll never decrease again. If you also have a leak, it will take a long time for malloc to run out of the recycled VM which means that you might not notice it.
So, use the purpose built leak detection tools.

What is private bytes, virtual bytes, working set?

I am trying to use the perfmon windows utility to debug memory leaks in a process.
This is how perfmon explains the terms:
Working Set is the current size, in bytes, of the Working Set of this process. The Working Set is the set of memory pages touched recently by the threads in the process. If free memory in the computer is above a threshold, pages are left in the Working Set of a process even if they are not in use. When free memory falls below a threshold, pages are trimmed from Working Sets. If they are needed they will then be soft-faulted back into the Working Set before leaving main memory.
Virtual Bytes is the current size, in bytes, of the virtual address space the process is using. Use of virtual address space does not necessarily imply corresponding use of either disk or main memory pages. Virtual space is finite, and the process can limit its ability to load libraries.
Private Bytes is the current size, in bytes, of memory that this process has allocated that cannot be shared with other processes.
These are the questions I have:
Is it the Private Bytes which I should measure to be sure if the process is having any leaks as it does not involve any shared libraries and any leaks, if happening, will come from the process itself?
What is the total memory consumed by the process? Is it the Virtual Bytes or is it the sum of Virtual Bytes and Working Set?
Is there any relation between Private Bytes, Working Set and Virtual Bytes?
Are there any other tools that give a better idea of the memory usage?
The short answer to this question is that none of these values are a reliable indicator of how much memory an executable is actually using, and none of them are really appropriate for debugging a memory leak.
Private Bytes refer to the amount of memory that the process executable has asked for - not necessarily the amount it is actually using. They are "private" because they (usually) exclude memory-mapped files (i.e. shared DLLs). But - here's the catch - they don't necessarily exclude memory allocated by those files. There is no way to tell whether a change in private bytes was due to the executable itself, or due to a linked library. Private bytes are also not exclusively physical memory; they can be paged to disk or in the standby page list (i.e. no longer in use, but not paged yet either).
Working Set refers to the total physical memory (RAM) used by the process. However, unlike private bytes, this also includes memory-mapped files and various other resources, so it's an even less accurate measurement than the private bytes. This is the same value that gets reported in Task Manager's "Mem Usage" and has been the source of endless amounts of confusion in recent years. Memory in the Working Set is "physical" in the sense that it can be addressed without a page fault; however, the standby page list is also still physically in memory but not reported in the Working Set, and this is why you might see the "Mem Usage" suddenly drop when you minimize an application.
Virtual Bytes are the total virtual address space occupied by the entire process. This is like the working set, in the sense that it includes memory-mapped files (shared DLLs), but it also includes data in the standby list and data that has already been paged out and is sitting in a pagefile on disk somewhere. The total virtual bytes used by every process on a system under heavy load will add up to significantly more memory than the machine actually has.
So the relationships are:
Private Bytes are what your app has actually allocated, but include pagefile usage;
Working Set is the non-paged Private Bytes plus memory-mapped files;
Virtual Bytes are the Working Set plus paged Private Bytes and standby list.
There's another problem here; just as shared libraries can allocate memory inside your application module, leading to potential false positives reported in your app's Private Bytes, your application may also end up allocating memory inside the shared modules, leading to false negatives. That means it's actually possible for your application to have a memory leak that never manifests itself in the Private Bytes at all. Unlikely, but possible.
Private Bytes are a reasonable approximation of the amount of memory your executable is using and can be used to help narrow down a list of potential candidates for a memory leak; if you see the number growing and growing constantly and endlessly, you would want to check that process for a leak. This cannot, however, prove that there is or is not a leak.
One of the most effective tools for detecting/correcting memory leaks in Windows is actually Visual Studio (link goes to page on using VS for memory leaks, not the product page). Rational Purify is another possibility. Microsoft also has a more general best practices document on this subject. There are more tools listed in this previous question.
I hope this clears a few things up! Tracking down memory leaks is one of the most difficult things to do in debugging. Good luck.
The definition of the perfmon counters has been broken since the beginning and for some reason appears to be too hard to correct.
A good overview of Windows memory management is available in the video "Mysteries of Memory Management Revealed" on MSDN: It covers more topics than needed to track memory leaks (eg working set management) but gives enough detail in the relevant topics.
To give you a hint of the problem with the perfmon counter descriptions, here is the inside story about private bytes from "Private Bytes Performance Counter -- Beware!" on MSDN:
Q: When is a Private Byte not a Private Byte?
A: When it isn't resident.
The Private Bytes counter reports the commit charge of the process. That is to say, the amount of space that has been allocated in the swap file to hold the contents of the private memory in the event that it is swapped out. Note: I'm avoiding the word "reserved" because of possible confusion with virtual memory in the reserved state which is not committed.
From "Performance Planning" on MSDN:
3.3 Private Bytes
3.3.1 Description
Private memory, is defined as memory allocated for a process which cannot be shared by other processes. This memory is more expensive than shared memory when multiple such processes execute on a machine. Private memory in (traditional) unmanaged dlls usually constitutes of C++ statics and is of the order of 5% of the total working set of the dll.
You should not try to use perfmon, task manager or any tool like that to determine memory leaks. They are good for identifying trends, but not much else. The numbers they report in absolute terms are too vague and aggregated to be useful for a specific task such as memory leak detection.
A previous reply to this question has given a great explanation of what the various types are.
You ask about a tool recommendation:
I recommend Memory Validator. Capable of monitoring applications that make billions of memory allocations.
http://www.softwareverify.com/cpp/memory/index.html
Disclaimer: I designed Memory Validator.
There is an interesting discussion here: http://social.msdn.microsoft.com/Forums/en-US/vcgeneral/thread/307d658a-f677-40f2-bdef-e6352b0bfe9e/
My understanding of this thread is that freeing small allocations are not reflected in Private Bytes or Working Set.
Long story short:
if I call
p=malloc(1000);
free(p);
then the Private Bytes reflect only the allocation, not the deallocation.
if I call
p=malloc(>512k);
free(p);
then the Private Bytes correctly reflect the allocation and the deallocation.

How can a program have a high virtual byte count while the private bytes are relatively low on Windows 32-bit?

I'm trying to get a better understanding of how Windows, 32-bit, calculates the virtual bytes for a program. I am under the impression that Virtual Bytes (VB) are the measure of how much of the user address space is being used, while the Private Bytes (PB) are the measure of actual committed and reserved memory on the system.
In particular, I have a server program I am monitoring which, when under heavy usage, will climb up to the 3GB limit for VBs. Around the same time the PB climb as well, but then quickly drop down to around 1 GB as the usage drops. The PB tend to then stay low, around the 1 GB mark, but the VB stay up around the 3 GB mark. I do not have access to the source code, so I am just using the basic Windows performance counters to monitor all of this. From a programming point of view, what memory concept do I not understand that makes this all possible? Is there a good reference to learn more about this?
What your reporting is most likely being caused by the process heap. There are two pieces to a memory allocation in Windows. The first piece is the continuous address space in your application for the memory to accessed through. On a 32 bit system not running the /3GB switch all your allocations must come out of the lower 2 GB of user address space. The second piece of the memory allocation is the actually memory for the allocation. This can be either RAM or part of the page file system on the hard disk. The OS handles moving allocations between RAM and the page file system in the background.
Most likely your application is using a Windows heap to handle all memory allocations. When a heap is created is reserves 1 MB of address space for the memory it will allocate. Until it actually needs memory associated with this address space no physical memory is actually used. If the heap needs more memory than 1 MB it uses a doubling algorithm to reserve more address space, and then commits physical memory when it needs it. The important thing to note is that once a heap reserves address space it never releases it.
Personally I found the following books and chapters useful when trying to understand memory management.
Advanced Windows Debugging - Chapter 6 This book has the most detailed look into the heap I have seen.
Windows Internals - Chapter 7 This book adds a bit of information not found in Advanced Windows Debugging; however, it does not give as good an overview.
It sounds to me like you have a garbage collector that's only kicking in once the memory pressure hits 1/3 (1 GB out of 3 GB).
As for the VB - don't worry! It's virtual! Honestly, nothing's been allocated, nothing's been committed. Focus on your private bytes - your real allocations.
There is such a thing as "Virtual Memory". It's a rather non-OS-specific concept in computer science. Microsoft has also written about Windows implementation of the thing.
A long story short, in Windows you can ask to reserve some memory without actually allocating any physical memory. It's like making some memory addresses reserved for future use. When you really need the memory, you allocate it physically (aka "commit" it).
I haven't needed to use this feature myself, so I don't know how it's used in real life programs, but I know it's there. I think the idea might be something like preserving pointers to some memory address and allocating the memory when needed, without having to change what the pointers actually point to.
Windows is notorious for having a variety of types of memory allocations, some of which are supersets of others. You've mentioned Private Bytes and Virtual Bytes. Private bytes, as you know, refers to memory allocated specifically to your process. Virtual bytes includes private bytes, as well as any shared memory, reserved memory, etc.
Even though in real life you only need to be concerned with private bytes and perhaps shared memory (Windows handles the rest, anyways), the Virtual Bytes count is often what users (and evaluators of your software) see and interpret as the memory usage of your process.
A good and up-to-date reference on the subject is the book titled Windows Via C/C++ by Jeffrey Richter, you should look for Chapter 13: "Windows Memory Architecture".

Resources