windows 内存管理api学习笔记
2021/11/21 7:12:48
本文主要是介绍windows 内存管理api学习笔记,对大家解决编程问题具有一定的参考价值,需要的程序猿们随着小编来一起学习吧!
文章目录
- 为什么使用虚拟内存
- 分配虚拟内存
- Windows内存管理API
- VirtualAlloc
- VirtualProtect
- VirtualFree
- C++代码
为什么使用虚拟内存
虚拟内存最适合用来管理大型对象或数据结构。
比如说,电子表格程序,有很多单元格,但是也许大多数的单元格是没有数据的,用不着分配空间。也许,你会想到用动态链表,但是访问又没有数组快。定义二维数组,就会浪费很多空间。
它的优点是同时具有数组的快速和链表的小空间的优点。
分配虚拟内存
如果你程序需要大块内存,你可以先保留内存,需要的时候再提交物理存储器。在需要的时候再提交才能有效的利用内存。一般来说,如果需要内存大于1M,用虚拟内存比较好。
Windows内存管理API
VirtualAlloc
在调用进程的虚拟地址空间中保留、提交或更改页面区域的状态。此函数分配的内存会自动初始化为零。
参数
[in, optional] LPVOID lpAddress, //开始地址 [in] SIZE_T dwSize, //大小 [in] DWORD flAllocationType, //类型 [in] DWORD flProtect //保护属性
- lpAddress:要分配的区域的起始地址。
一般情况下,你不需要指定“开始地址”,因为你不知道进程的那段空间是不是已经被占用了;所以你可以用NULL。 - dwSize:区域的大小,以字节为单位。
- flAllocationType:
“类型”有
MEM_RESERVE(保留)保留区域不占用任何物理存储。
MEM_RELEASE(释放)
MEM_COMMIT(提交)为指定的保留内存页面分配内存费用
如果你要保留的是长久不会释放的内存区,就保留在较高的空间区域,这样不会产生碎片。用这个类型标志可以达到:
MEM_RESERVE|MEM_TOP_DOWN。 - flProtect:要分配的页面区域的内存保护。
返回值
如果函数成功,则返回值是页面分配区域的基地址。
如果函数失败,则返回值为NULL。要获取扩展错误信息,请调用GetLastError。
VirtualProtect
更改对调用进程虚拟地址空间中已提交页面区域的保护。
参数
[in] LPVOID lpAddress, [in] SIZE_T dwSize, [in] DWORD flNewProtect, //新属性 [out] PDWORD lpflOldProtect //旧属性
返回值
如果函数成功,则返回值非零。
如果函数失败,则返回值为零。要获取扩展错误信息,请调用 GetLastError。
VirtualFree
调用进程的虚拟地址空间内释放、取消提交或释放和取消提交页面区域。
参数
[in] LPVOID lpAddress, //指向要释放的页面区域的基地址的指针。 [in] SIZE_T dwSize, //要释放的内存区域的大小,以字节为单位。 [in] DWORD dwFreeType //释放操作的类型。
- dwFreeType类型
MEM_DECOMMIT 取消提交页面的指定区域。操作后,页面处于保留状态。
MEM_RELEASE 释放指定的页面区域或占位符(对于占位符,地址空间被释放并可用于其他分配)。此操作后,页面处于空闲状态。
返回值
如果函数成功,则返回值非零。
如果函数失败,则返回值为 0(零)。要获取扩展错误信息,请调用 GetLastError
C++代码
自定义内存状况输出函数
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; }
保留空间
//输出内存保留前情况 printMemStatus(); //保留512mb的空间 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();
提交
//提交 128mb 空间 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();
修改页保护属性
DWORD protect; VirtualProtect(pV, 1024*4, PAGE_READONLY,&protect) ; int * iP=(int*)pV; iP[1023] = 1; //报错,在这一页之中 iP[1024] = 1; //不报错
释放
//只释放物理内存 VirtualFree((int*)pV,100*1024*1024,MEM_DECOMMIT); cout<<"******************************"<<endl; cout<<"After VirtualFree MEM_DECOMMIT"<<endl; cout<<"******************************"<<endl; printMemStatus(); //释放全部空间 VirtualFree(pV,0,MEM_RELEASE); cout<<"******************************"<<endl; cout<<"After VirtualFree MEM_RELEASE"<<endl; cout<<"******************************"<<endl; printMemStatus();
完整代码
#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(); //保留512mb的空间 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(); //提交 128mb 空间 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(); //更改页面保护属性 DWORD protect; VirtualProtect(pV, 1024*4, PAGE_READONLY,&protect) ; int * iP=(int*)pV; //iP[1023] = 1; //报错,在这一页之中 iP[1024] = 1; //不报错 //只释放100mb物理内存 VirtualFree((int*)pV,100*1024*1024,MEM_DECOMMIT); cout<<"******************************"<<endl; cout<<"After VirtualFree MEM_DECOMMIT"<<endl; cout<<"******************************"<<endl; printMemStatus(); //释放全部空间 VirtualFree(pV,0,MEM_RELEASE); cout<<"******************************"<<endl; cout<<"After VirtualFree MEM_RELEASE"<<endl; cout<<"******************************"<<endl; printMemStatus(); }
这篇关于windows 内存管理api学习笔记的文章就介绍到这儿,希望我们推荐的文章对大家有所帮助,也希望大家多多支持为之网!
- 2024-11-24Java中定时任务实现方式及源码剖析
- 2024-11-24Java中定时任务实现方式及源码剖析
- 2024-11-24鸿蒙原生开发手记:03-元服务开发全流程(开发元服务,只需要看这一篇文章)
- 2024-11-24细说敏捷:敏捷四会之每日站会
- 2024-11-23Springboot应用的多环境打包入门
- 2024-11-23Springboot应用的生产发布入门教程
- 2024-11-23Python编程入门指南
- 2024-11-23Java创业入门:从零开始的编程之旅
- 2024-11-23Java创业入门:新手必读的Java编程与创业指南
- 2024-11-23Java对接阿里云智能语音服务入门详解