虚拟内存的按需调拨
windows C++ 虚拟内存的按需调拨
虚拟内存的按需调拨
/*------------------------------------------------------------------------
24-SEHAndMemory.cpp
演示虚拟内存的按需调拨
-----------------------------------------------------------------------*/
#include <windows.h>
#include <tchar.h>
#include <locale.h>
#define PAGELIMIT 80
LPBYTE lpNxtPage;
DWORD dwPages = 0;
DWORD dwPageSize;//页面大小,一般为4KB
INT PageFualtExceptionFilter(DWORD dwCode) {
LPVOID lpvResult;
//不是非法访问内存
if (dwCode != EXCEPTION_ACCESS_VIOLATION) {//线程试图读写一个虚拟内存地址,但在这个地址它并不具备相应权限
return EXCEPTION_EXECUTE_HANDLER;//执行except块的异常处理程序代码
}
//当超过指定的页面数时
if (dwPages >= PAGELIMIT) {
return EXCEPTION_EXECUTE_HANDLER;//执行except块的异常处理程序代码
}
//非法访问内存,则为预订的空间提交下一页物理存储器
lpvResult = VirtualAlloc((LPVOID)lpNxtPage, dwPageSize, MEM_COMMIT, PAGE_READWRITE);
if (lpvResult == NULL) {
return EXCEPTION_EXECUTE_HANDLER;//执行except块的异常处理程序代码
}
//提交成功
dwPages++;
lpNxtPage += dwPageSize;
_tprintf(_T("第%d页提交成功!\n"), dwPages);
return EXCEPTION_CONTINUE_EXECUTION; //重新执行触发异常的那条CPU指令
}
int main() {
_tsetlocale(LC_ALL, _T("chs"));
LPVOID lpvBase; LPTSTR lpPtr; BOOL bSuccess;
SYSTEM_INFO sSysInfo;
GetSystemInfo(&sSysInfo);
dwPageSize = sSysInfo.dwPageSize;
_tprintf(_T("CPU页面大小为%dKB.\n"), sSysInfo.dwPageSize / 1024);
//预订存储器
lpvBase = VirtualAlloc(NULL, PAGELIMIT*dwPageSize, MEM_RESERVE, PAGE_NOACCESS);
lpPtr = (LPTSTR)(lpNxtPage = (LPBYTE)lpvBase);
for (DWORD i = 0; i < PAGELIMIT*dwPageSize / sizeof(TCHAR); i++) {
__try {
lpPtr[i] = _T('a');//写入一个字节的数据
}
__except (PageFualtExceptionFilter(GetExceptionCode())) {
_tprintf(_T("异常被处理\n"));
//ExitProcess(GetLastError());
}
}
bSuccess = VirtualFree(lpvBase, 0, MEM_RELEASE);
_tprintf(_T("释放操作%s.\n"), bSuccess ? _T("成功") : _T("失败"));
_tsystem(_T("PAUSE"));
return 0;
}