zoukankan      html  css  js  c++  java
  • 在进程空间使用虚拟内存(Windows 核心编程)

    虚拟内存空间

    • 如今的 Windows 操作系统不仅可以运行多个应用程序,还可以让每一个应用程序享受到约 4 GB 的虚拟内存空间(包括系统占用),假如内存为 4 GB 的话。那为什么 Window 可以做到呢,这归功于虚拟内存空间和页交换文件的快速交换才能实现这样的功能
      在这里插入图片描述

    0x02 使用虚拟内存空间

    • 那么程序如何才能使用虚拟内存空间呢,其实很简单,一般为这几个步骤:首先需要预定虚拟内存空间,因为 Windows 给出的原则是先预定才能够使用,其次需要在预定的地址空间调拨物理存储器,因为只有这样才能使用预定的虚拟内存地址空间,最后在使用完预定的虚拟内存地址空间后需要释放它,便于下一次使用
    • 来看看使用虚拟内存空间需要哪些函数:
      (1) VirtualAlloc:预定虚拟内存空间和调拨物理储存器 (2) VirtualFree:撤销物理储存器并且释放预定区域
    • 值得注意的是预定虚拟内存空间和调拨物理储存器使用的是用一个函数,分开使用便于理解,例子如下

    注:虚拟内存空间并不是堆空间,堆空间是纯内存空间,而虚拟内存空间则是硬盘空间

    #include <Windows.h>
    #include <iostream>
    #include <tlhelp32.h>
    using namespace std;
    
    int main(int argc, char **argv)
    {
    	PVOID AddressReserve, AddressUse;
    	
    	// 预定 100MB 大小的虚拟内存区域
    	AddressReserve = VirtualAlloc(NULL, 100 * 1024 * 1024, MEM_TOP_DOWN | MEM_RESERVE, PAGE_READWRITE);
    
    	// 在预定完的虚拟内存区域调拨 1MB 大小的物理储存器
    	AddressUse = VirtualAlloc(AddressReserve, 1 * 1024 * 1024, MEM_COMMIT, PAGE_READWRITE);
    	memset(AddressUse, 'A', 1*1024*1024);
    
    	MEMORY_BASIC_INFORMATION MemoryInfo = { 0 };
    
    	// 查询已经调拨物理储存器虚拟内存地址的状态
    	if (VirtualQuery(AddressUse, &MemoryInfo, sizeof(MemoryInfo)))
    	{
    		cout << "[*] 页面大小为: " << MemoryInfo.RegionSize << endl;
    		cout << "[*] 页面状态为: " << (HANDLE)MemoryInfo.State << endl;
    	}
    
    	// 释放预定区域
    	VirtualFree(AddressReserve, 0, MEM_RELEASE);
    	return 0;
    }
    
    
    • 值得注意的是使用 VirtualAlloc 预定虚拟内存地址空间的时候第二个参数必须传 MEM_RESERVE,而给预定地址空间调拨物理储存器的时候第二个参数必须传 MEM_COMMIT,如果是预定的同时调拨就传 MEM_RESERVE | MEM_COMMIT。在最后使用 VirtualFree 释放的时候,释放的是预定的全部虚拟内存地址,而不只是调拨物理储存器的虚拟内存地址,所以我给第二个参数传 0,给第三个参数传 MEM_RELEASE。为了更直观的看出虚拟内存空间的分配过程,可以观察分配时内存空间的变化:
    • 预定区域,成功返回基址为 0x79A50000:
      在这里插入图片描述
    • 调拨物理储存器并覆盖为 ‘A’ 字符:
      在这里插入图片描述
      在这里插入图片描述
    • 释放预定区域:
      在这里插入图片描述
    • 在程序的最后调用了 VirtualQuery 函数获取了刚刚调拨物理储存器的虚拟内存地址空间信息,打印结果如下:
      在这里插入图片描述
    • 页面状态码的对应的页面状态,0x1000 表示该区域已经调拨了物理存储器
    MEM_COMMIT
    为0x1000
    表示已在内存中或磁盘上的页面文件中为其分配了物理存储的已提交页面。
    MEM_FREE
    为0x10000
    表示调用进程无法访问且可以分配的空闲页面。对于空闲页面,未定义AllocationBase,AllocationProtect,Protect和Type成员中的信息。
    MEM_RESERVE
    为0x2000
    表示保留进程的虚拟地址空间范围而不分配任何物理存储的保留页面。对于保留页面,Protect成员中的信息未定义。
    
  • 相关阅读:
    linux各文件夹的作用
    CodeIgniter的URL传过来的中文参数处理错误的修复
    syn_ack攻击
    分治排序
    Linux Shell学习笔记
    sql题型
    jquery ajax
    json 字符串与对象之间的转换
    常用的VIM命令列表 移动光标
    visual c++ 2012 内存泄漏检测方法
  • 原文地址:https://www.cnblogs.com/csnd/p/11800510.html
Copyright © 2011-2022 走看看