在进程空间使用虚拟内存(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成员中的信息未定义。
在进程空间使用虚拟内存(Windows 核心编程)的更多相关文章
- 线程操作与进程挂起(Windows核心编程)
0x01 线程挂起与切换 对于挂起进程,挂起线程则比较简单,利用 ResumeThread 与 SuspendThread 即可,当线挂起时线程用户状态下的一切操作都会暂停 #include < ...
- Windows核心编程:第4章 进程
Github https://github.com/gongluck/Windows-Core-Program.git //第4章 进程.cpp: 定义应用程序的入口点. // #include &q ...
- C++Windows核心编程读书笔记
转自:http://www.makaidong.com/%E5%8D%9A%E5%AE%A2%E5%9B%AD%E6%96%87/71405.shtml "C++Windows核心编程读书笔 ...
- 【转】《windows核心编程》读书笔记
这篇笔记是我在读<Windows核心编程>第5版时做的记录和总结(部分章节是第4版的书),没有摘抄原句,包含了很多我个人的思考和对实现的推断,因此不少条款和Windows实际机制可能有出入 ...
- 《windows核心编程系列》十六谈谈内存映射文件
内存映射文件允许开发人员预订一块地址空间并为该区域调拨物理存储器,与虚拟内存不同的是,内存映射文件的物理存储器来自磁盘中的文件,而非系统的页交换文件.将文件映射到内存中后,我们就可以在内存中操作他们了 ...
- Windows核心编程随笔
最近在学习Windows底层原理,准备写个系列文章分享给大家,Michael Li(微软实习期间的Mentor,为人超好)在知乎回答过一些关于学习Windows原理的书籍推荐,大家可以拜读其中一本来入 ...
- windows核心编程 - 线程同步机制
线程同步机制 常用的线程同步机制有很多种,主要分为用户模式和内核对象两类:其中 用户模式包括:原子操作.关键代码段 内核对象包括:时间内核对象(Event).等待定时器内核对象(WaitableTim ...
- windows核心编程---第八章 使用内核对象进行线程同步
使用内核对象进行线程同步. 前面我们介绍了用户模式下线程同步的几种方式.在用户模式下进行线程同步的最大好处就是速度非常快.因此当需要使用线程同步时用户模式下的线程同步是首选. 但是用户模式下的线程同步 ...
- 【windows核心编程】 第六章 线程基础
Windows核心编程 第六章 线程基础 欢迎转载 转载请注明出处:http://www.cnblogs.com/cuish/p/3145214.html 1. 线程的组成 ① 一个是线程的内核 ...
- 《Windows核心编程》读书笔记 上
[C++]<Windows核心编程>读书笔记 这篇笔记是我在读<Windows核心编程>第5版时做的记录和总结(部分章节是第4版的书),没有摘抄原句,包含了很多我个人的思考和对 ...
随机推荐
- DLL劫持学习及复现
0x01 dll简介 在Windows系统中,为了节省内存和实现代码重用,微软在Windows操作系统中实现了一种共享函数库的方式.这就是DLL(Dynamic Link Library),即动态链接 ...
- jwt以及如何使用jwt实现登录
目录 jwt的使用和使用jwt进行登录 什么是jwt jwt的组成 为什么选择jwt session的缺点 jwt的优点 一个jwt的工具类 将jwt和登录进行结合 axios方式将jwt放在head ...
- Hi3559AV100 NNIE开发(5)mobilefacenet.wk仿真成功量化及与CNN_convert_bin_and_print_featuremap.py输出中间层数据对比过程
前面随笔给出了NNIE开发的基本知识,下面几篇随笔将着重于Mobilefacenet NNIE开发,实现mobilefacenet.wk的chip版本,并在Hi3559AV100上实现mobilefa ...
- OpenGL光照计算中法线矩阵原理及推到过程
问题起源 在计算漫反射关照时,需要用到法线,通过法线和光线的点乘值,计算漫反射的产生的光线强度,所以需要从顶点着色器中将法线数据传递到片源着色器中,但是片源着色器中的顶点坐标是经过了模型矩阵变化过的世 ...
- markdown快捷输入
标题: 输入方式:#+空格+标题名,几级标题就敲几个# 注:最大支持六级标题 字体 加粗:在要加粗的字体前后加** 斜体:在要倾斜的字体前后加* 斜体加粗:在要倾斜并加粗的字体前后加*** 删除线:在 ...
- vue 快速入门 系列 —— vue 的基础应用(上)
其他章节请看: vue 快速入门 系列 vue 的基础应用(上) Tip: vue 的基础应用分上下两篇,上篇是基础,下篇是应用. 在初步认识 vue一文中,我们已经写了一个 vue 的 hello- ...
- [图论]剑鱼行动:prim
剑鱼行动 目录 剑鱼行动 Description Input Output Sample Input Sample Output 解析 难点 代码 Description 给出N个点的坐标,对它们建立 ...
- 动图:删除链表的倒数第 N 个结点
本文主要介绍一道面试中常考链表删除相关的题目,即 leetcode 19. 删除链表的倒数第 N 个结点.采用 双指针 + 动图 的方式进行剖析,供大家参考,希望对大家有所帮组. 19. 删除链表的倒 ...
- 腾讯高级工程师带你玩转打包利器webpack
随着前端领域飞速发展,webpack将前端不断出现的新模块.新资源.新需求,进行自动化整合.梳理.输出,极大提高了我们的工作效率,成为前端构建领域里最炙手可热的构建工具. 不少人webpack 的使用 ...
- 算法很美,听我讲完这些Java经典算法包你爱上她
大家好,我是小羽. 对于编程来说的话,只有掌握了算法才是了解了编程的灵魂,算法对于新手来说的话,属实有点难度,但是以后想有更好的发展,得到更好的进阶的话,对算法进行系统的学习是重中之重的. 对于 Ja ...