Virtual size troubleshooting

The server application in which I am working on building using C ++ on Windows ends due to lack of memory when the Virtual Size reaches somewhere around 2 GB (32-bit application with support for a large address). However, I noticed that Private Bytes are significantly smaller. Current statistics:

Virtual size: 2.6 GB Private bytes: 1.6 GB

The difference in these two numbers is 1 GB. So my questions are:

  • What is the difference of 1 GB?
  • Does my application run out of memory due to virtual size or private bytes?

I also run my application through the VMMap utility, and I notice that "Private data" usually exceeds the fixed size by an order of magnitude. In other words, the total size for private data can be 200 MB, but the fixed size is only 20 MB. I'm not quite sure what personal data is, but based on my research so far, this seems to indicate that it is just part of the heap.

EDIT:

I searched for memory leaks with Purify, but I did not find anything useful. A memory leak in the form of memory without pointers does not seem to be a problem, but a memory leak in terms of holding the memory for too long can be a problem, I have not studied it yet. However, the key point is understanding why virtual size causes memory problems. Question No. 1 is the most important for me to understand.

+4
source share
4 answers

This will require a little explanation, so stick with me here.

Firstly, this topic is a confusing swamp of conflicting terms, so please throw away all the concepts that you have about "virtual memory", something related to disks.

  • Physical memory is the memory stored on a physical device. This usually refers to system RAM, but can also be disk buffers, NIC buffers, VRAM graphics cards, etc.
  • Virtual memory is a set of ranges of physical addresses mapped to user (virtual) address ranges so that memory access can be secure and shared.

A quick note on why we do this: if we were passing direct memory addresses, we could (possibly) have only one memory store. This is inconvenient and bad for performance. When the virtual address is converted to a physical address outside the range of system memory (RAM), the processor generates a page error. This is signaled by the OS interrupt handler, which can then delegate the memory access operation to another device. Useful!

On a 32-bit Windows system, the maximum amount of virtual memory that a process can process at any given time is 2 GB. This can be increased up to 3 GB using AWE or 4 GB using /4GT and AWE. This does not mean that the process can only allocate 2 GB (or 3 GB / 4 GB depending on the previously discussed settings) memory. It just means that it cannot have simultaneous access to more than that.

For example, if you open a file with a memory map of 1 GB, the use of your virtual memory will increase by 1 GB. You do not touch RAM and disk, but you have allocated a block of virtual address space for your process. If then you want to allocate 1.1 GB of RAM simultaneously with the presence of this file with a memory map, you will not be able to. You must cancel the file from your process first. Remember that memory can still be allocated and filled with data, but not actually mapped in your process. If your computer has 8 GB of RAM, you can fill 6 GB with data and map 2 GB to your process. When you need to use another section of this memory, you must unlock the existing block and display another section.

So, for the difference you see:

  • Private bytes tell you how many bytes of virtual device memory are mapped in your process, excluding virtual memory shared by other processes (e.g. mapped files, global heap, etc.).

  • The working set tells you how many bytes of physical memory you are actively using. This includes physical memory, device buffers, and associated files. This is a rather strange figure, since it is equivalent to touching a physical memory + a mapped virtual non-system memory. In general, you should completely ignore this figure. This is practically useless for debugging memory leaks.

  • Virtual bytes are the total amount of virtual memory that you have mapped.

The difference is that you have mapped shared virtual memory, such as a bunch of DLL files or a global heap block, into your process. The difference indicates that the total size of these shared mappings is approximately 1 GB.

Keep in mind that none of this has anything to do with sharing, that is, transferring pages of system memory to disk (the so-called “swap file”) to increase the availability of fast system resources (RAM). The naming of this file did not end the confusion in this area of ​​Windows, and I will be delighted when Microsoft finally decides to call it "swap" rather than "virtual memory" or "page file".

+6
source
  • Virtual size vs Private bytes: What are private bytes, virtual bytes, working set? (see quote below)
  • Your application is likely to reach the virtual size limit of 2 GB, especially. as you yourself see this behavior.
  • /LARGEADDRESSAWARE expands the virtual size limit for your application on Win32 operating systems only when booting the system using / 3GB AKA 4GT enabled

Virtual bytes are the shared virtual address space occupied by the entire process. This is similar to a working set, in the sense that it includes memory-mapped files (shared DLLs), but also includes data in the backup list and data that has already been unloaded and sitting somewhere in the swap file. The shared virtual bytes used by each process in a system with a large load will be significantly more memory than it actually is.

So, the relationship:

  • Private bytes are what your application really allocated, but enable the use of the swap file;
  • The working set is unencrypted private bytes plus files with memory mapping;
  • Virtual bytes are a working set plus individual bytes and a fallback list.
+2
source

I had a similar problem on my machine where the Win32 application for C / C ++ /. NET did not have enough memory. It consumed all 2 GB of virtual addresses. It looked like "Exhaustion of virtual addresses" because Process Explorer showed only about 900 MB of memory taken by the application. VMMap showed 1.6 GB of private data and about 700 MB of unallocated memory.

The reason was more than simple. Verifier application (C: \ Windows \ SysWOW64 \ appverif.exe), which was configured to test the application (the main tests were noted - vfbasics.dll). After uninstalling the application from Application Verifier, it worked fine.

+1
source

Just a comment: turning on a large address allows only the OS to signal that it can safely share the virtual address space of processes created from this particular executable file in 3: 1 mode instead of the usual 2: 2. There are various reasons why the application must explicitly identify, that it supports 3: 1 separation, but the most obvious is that in 2: 2 verification mode, the virtual address MSB can be used to check whether the address of the kernel part of the virtual address space or part of the user. At 3: 1, this test is no longer valid, since the MSB is also 1 for 1/3 of the virtual address space user. This requires that the drivers that this application can invoke must also be aware of a possible 3: 1 split, and should use a different method to verify that the given virtual address does not belong to user space.

You should still explicitly tell the kernel to enable support for 3: 1 VA spatial separation, as R. R pointed out.

0
source

All Articles