windows Memory Management api learning notes

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(); 
}

Keywords: Windows

Added by john9292 on Sun, 21 Nov 2021 13:02:58 +0200