Why use virtual memory
Virtual memory is best used to manage large objects or data structures.
For example, in a spreadsheet program, there are many cells, but perhaps most cells have no data and do not need to allocate space. Perhaps, you will think of using dynamic linked list, but the access is not as fast as array. Defining a two-dimensional array wastes a lot of space.
Its advantage is that it has the advantages of fast array and small space of linked list at the same time.
Allocate virtual memory
If your program needs large blocks of memory, you can reserve memory first and submit physical memory when needed. Commit when necessary to make effective use of memory. Generally speaking, if the required memory is greater than 1M, it is better to use virtual memory.
Windows Memory Management API
VirtualAlloc
Preserve, commit, or change the state of the page area in the virtual address space of the calling process. The memory allocated by this function is automatically initialized to zero.
parameter
[in, optional] LPVOID lpAddress, //Start address [in] SIZE_T dwSize, //size [in] DWORD flAllocationType, //type [in] DWORD flProtect //Protection properties
- lpAddress: the starting address of the area to be assigned.
Generally, you don't need to specify the "start address", because you don't know whether the space of the process has been occupied; So you can use NULL. - dwSize: the size of the area, in bytes.
- flAllocationType:
"Type" has
MEM_RESERVE the reserved area does not occupy any physical storage.
MEM_RELEASE
MEM_COMMIT allocates memory charges for the specified reserved memory pages
If you want to keep the memory area that will not be released for a long time, keep it in a higher space area, so that there will be no fragmentation. With this type of flag, you can achieve:
MEM_RESERVE|MEM_TOP_DOWN. - flProtect: memory protection for the page area to be allocated.
Return value
If the function succeeds, the return value is the base address of the page allocation area.
If the function fails, the return value is NULL. To get extended error information, call GetLastError.
VirtualProtect
Change the protection of the submitted page area in the calling process virtual address space.
parameter
[in] LPVOID lpAddress, [in] SIZE_T dwSize, [in] DWORD flNewProtect, //new property [out] PDWORD lpflOldProtect //Old attribute
Return value
If the function succeeds, the return value is non-zero.
If the function fails, the return value is zero. To get extended error information, call GetLastError.
VirtualFree
Release, uncommit, or release and uncommit the page area within the virtual address space of the calling process.
parameter
[in] LPVOID lpAddress, //Pointer to the base address of the page area to be released. [in] SIZE_T dwSize, //The size of the memory area to free, in bytes. [in] DWORD dwFreeType //Type of release operation.
- dwFreeType type
MEM_ Commit uncommitted the specified area of the page. After the operation, the page is kept.
MEM_RELEASE releases the specified page area or placeholder (for placeholders, the address space is released and available for other allocations). After this operation, the page is idle.
Return value
If the function succeeds, the return value is non-zero.
If the function fails, the return value is 0 (zero). To get extended error information, call GetLastError
C + + code
Custom memory status output function
void printMemStatus() { MEMORYSTATUS memStatusVirtual; GlobalMemoryStatus(&memStatusVirtual); cout << "dwAvailPhys :"<<memStatusVirtual.dwAvailPhys/1024/1024<<"MB"<<endl; cout << "dwAvailPageFile :"<<memStatusVirtual.dwAvailPageFile/1024/1024<<"MB"<<endl; cout << "dwAvailVirtual :"<<memStatusVirtual.dwAvailVirtual/1024/1024<<"MB"<<endl; }
Reserved space
//Output before memory retention printMemStatus(); //Reserve 512mb of space LPVOID pV=VirtualAlloc(NULL,512*1024*1024,MEM_RESERVE|MEM_TOP_DOWN,PAGE_READWRITE); if(pV==NULL){ cout<<"VirtualAlloc MEM_RESERVE failed."<<endl; return 0; } cout<<"******************************"<<endl; cout<<"After VirtualAlloc MEM_RESERVE"<<endl; cout<<"******************************"<<endl; //Memory condition after output retention printMemStatus();
Submit
//Submit 128mb of space LPVOID pP=VirtualAlloc(pV,128*1024*1024,MEM_COMMIT,PAGE_READWRITE); if(pP==NULL){ cout<<"VirtualAlloc MEM_COMMIT failed."<<endl; return 0; } cout<<"******************************"<<endl; cout<<"After VirtualAlloc MEM_COMMIT"<<endl; cout<<"******************************"<<endl; printMemStatus();
Modify page protection properties
DWORD protect; VirtualProtect(pV, 1024*4, PAGE_READONLY,&protect) ; int * iP=(int*)pV; iP[1023] = 1; //An error is reported on this page iP[1024] = 1; //No error reporting
release
//Free only physical memory VirtualFree((int*)pV,100*1024*1024,MEM_DECOMMIT); cout<<"******************************"<<endl; cout<<"After VirtualFree MEM_DECOMMIT"<<endl; cout<<"******************************"<<endl; printMemStatus(); //Free up all space VirtualFree(pV,0,MEM_RELEASE); cout<<"******************************"<<endl; cout<<"After VirtualFree MEM_RELEASE"<<endl; cout<<"******************************"<<endl; printMemStatus();
Complete code
#include <cstdio> #include <memoryapi.h> #include <Windows.h> #include <winbase.h> #include <iostream> using namespace std; void printMemStatus() { MEMORYSTATUS memStatusVirtual; GlobalMemoryStatus(&memStatusVirtual); cout << "dwAvailPhys :"<<memStatusVirtual.dwAvailPhys/1024/1024<<"MB"<<endl; cout << "dwAvailPageFile :"<<memStatusVirtual.dwAvailPageFile/1024/1024<<"MB"<<endl; cout << "dwAvailVirtual :"<<memStatusVirtual.dwAvailVirtual/1024/1024<<"MB"<<endl; } int main() { printMemStatus(); //Reserve 512mb of space LPVOID pV=VirtualAlloc(NULL,512*1024*1024,MEM_RESERVE|MEM_TOP_DOWN,PAGE_READWRITE); if(pV==NULL){ cout<<"VirtualAlloc MEM_RESERVE failed."<<endl; return 0; } cout<<"******************************"<<endl; cout<<"After VirtualAlloc MEM_RESERVE"<<endl; cout<<"******************************"<<endl; printMemStatus(); //Submit 128mb of space LPVOID pP=VirtualAlloc(pV,128*1024*1024,MEM_COMMIT,PAGE_READWRITE); if(pP==NULL){ cout<<"VirtualAlloc MEM_COMMIT failed."<<endl; return 0; } cout<<"******************************"<<endl; cout<<"After VirtualAlloc MEM_COMMIT"<<endl; cout<<"******************************"<<endl; printMemStatus(); //Change page protection properties DWORD protect; VirtualProtect(pV, 1024*4, PAGE_READONLY,&protect) ; int * iP=(int*)pV; //iP[1023] = 1; // An error is reported on this page iP[1024] = 1; //No error reporting //Only 100mb of physical memory is released VirtualFree((int*)pV,100*1024*1024,MEM_DECOMMIT); cout<<"******************************"<<endl; cout<<"After VirtualFree MEM_DECOMMIT"<<endl; cout<<"******************************"<<endl; printMemStatus(); //Free up all space VirtualFree(pV,0,MEM_RELEASE); cout<<"******************************"<<endl; cout<<"After VirtualFree MEM_RELEASE"<<endl; cout<<"******************************"<<endl; printMemStatus(); }