在32位windows上只能看到最大3GB的内存空间,而且每个应用程序只能访问4GB的的内存,这个限制是windows独有的,为了使程序能够访问大于4GB的内存空间,需要使用AWE编程接口,同时需要开启PAE,让系统支持大于3GB的内存,开启PAE最大能支持128GB的内存。

PAE开启

在windows 7及以上的系统主要使用BCDEdit命令而XP系统使用的是修改boot.ini文件的方式,下面主要介绍的是windows 7 上开启PAE的方式

在命令行下输入BCDEdit /set PAE forceenable windows

另外如果需要扩大用户分区可以打开/3GB开关,这个开关在windows 7上用命令:BCDEdit /set IncreaseUseVa 3072(后面的数字代表的是用户分区的大小,3072正是3GB)

另外编译选项需要打开/LARGEADDRESSAWARE开关

AWE编程接口

开启PAE之后想要自己的程序能够访问到超过4GB的内存,需要使用AWE的编程接口,AWE(Address Windowing Extensions)是地址窗口扩展。

使用AWE时,所有物理页面的交换控制就由应用程序自己控制

使用的基本步骤:

1. 使用VirtualAlloc + MEM_PHYSICAL分配保留一段地址空间

2. 准备用于存储页表的数组

3. 申请分配物理内存(AllocateUserPhysicalPages)

4. 将物理内存映射到“窗口”中(MapUserPhysicalPages)

5. 对映射的内存进行读写操作

6. 释放物理内存页面(FreeUserPhysicalPages)

7. 释放对应的保留地址空间

下面是使用AWE的简单例子

#define MEMORY_REQUESTED 1024 * 1024 * 1024 //1GB
BOOL bResult; // generic Boolean value
ULONG_PTR NumberOfPages; // number of pages to request
ULONG_PTR NumberOfPagesInitial; // initial number of pages requested
ULONG_PTR *aPFNs1; // page info; holds opaque data
ULONG_PTR *aPFNs2; // page info; holds opaque data
PVOID lpMemReserved; // AWE window
SYSTEM_INFO sSysInfo; // useful system information
int PFNArraySize; // memory to request for PFN array
TCHAR* pszData;
TCHAR pszReadData[100]; MEMORYSTATUSEX ms = {sizeof(MEMORYSTATUSEX)};
GlobalMemoryStatusEx(&ms);
//使用VirtualAlloc + MEM_PHYSICAL分配保留一段地址空间
lpMemReserved = VirtualAlloc( NULL,MEMORY_REQUESTED, MEM_RESERVE | MEM_PHYSICAL, PAGE_READWRITE );
//计算需要的物理页面大小 以及物理页面需要的页表数组大小
GetSystemInfo(&sSysInfo); // fill the system information structure
//向上取整,计算出需要多少个页表项
NumberOfPages = (MEMORY_REQUESTED + sSysInfo.dwPageSize - 1)/sSysInfo.dwPageSize;
PFNArraySize = NumberOfPages * sizeof (ULONG_PTR);
//2 准备物理页面的页表数组数据
aPFNs1 = (ULONG_PTR *) HeapAlloc(GetProcessHeap(), 0, PFNArraySize);
aPFNs2 = (ULONG_PTR *) HeapAlloc(GetProcessHeap(), 0, PFNArraySize);
NumberOfPagesInitial = NumberOfPages;
//3 分配物理页面
bResult = AllocateUserPhysicalPages( GetCurrentProcess(),&NumberOfPages,aPFNs1 );
bResult = AllocateUserPhysicalPages( GetCurrentProcess(),&NumberOfPages,aPFNs2 );
//4 映射第一个1GB到保留的空间中
bResult = MapUserPhysicalPages( lpMemReserved,NumberOfPages,aPFNs1 );
pszData = (TCHAR*)lpMemReserved;
_tcscpy(pszData,_T("这是第一块物理内存"));
//5 映射第二个1GB到保留的空间中
bResult = MapUserPhysicalPages( lpMemReserved,NumberOfPages,aPFNs2 );
_tcscpy(pszData,_T("这是第二块物理内存"));
//6 再映射回第一块内存,并读取开始部分
bResult = MapUserPhysicalPages( lpMemReserved,NumberOfPages,aPFNs1 );
_tcscpy(pszReadData,pszData);
//7 取消映射
bResult = MapUserPhysicalPages( lpMemReserved,NumberOfPages,NULL );
//8 释放物理页面
bResult = FreeUserPhysicalPages( GetCurrentProcess(),&NumberOfPages,aPFNs1 );
bResult = FreeUserPhysicalPages( GetCurrentProcess(),&NumberOfPages,aPFNs2 );
//9 释放保留的"窗口"空间
bResult = VirtualFree( lpMemReserved,0, MEM_RELEASE );
//10 释放页表数组
bResult = HeapFree(GetProcessHeap(), 0, aPFNs1);
bResult = HeapFree(GetProcessHeap(), 0, aPFNs2);
_tsystem(_T("PAUSE"));

上述代码中,虽然只保留了1GB的虚拟地址空间,但是这1GB的虚拟地址空间通过映射的方式,映射到具体不同的真实内存中,这个就是PAE能访问大于4GB内存的秘密,通过对分页机制的了解,4字节的虚拟地址空间能够映射4KB的一页内存,所以经过简单的计算,其实没多映射1GB的内存其实只需要1M的数组来存储这些页表项。

64位的windows不再也没有必要支持AWE技术,因为这个技术就是为了解决应用程序访问内存不足的情况,但是在64位系统中不存在这个问题,也许有朝一日64位的操作系统也会出现能够访问的内存太少的情况,这个时候说不定会出现类似于AWE的技术

windows PAE扩展和AWE编程的更多相关文章

  1. Windows Embedded Compact 7网络编程概述(上)

    如今,不论是嵌入式设备.PDA还是智能手机,网络都是必不可少的模块.网络使人们更方便地共享设备上的信息和资源.而且,利用智能手机浏览互联网,也逐渐成为生活中的常见手段.物联网所倡导的物物相联,也离不开 ...

  2. windows下的socket网络编程

    windows下的socket网络编程 windows下的socket网络编程 clinet.c 客户端 server.c 服务器端 UDP通信的实现 代码如下 已经很久没有在windows下编程了, ...

  3. windows下的socket网络编程(入门级)

    windows下的socket网络编程 clinet.c 客户端 server.c 服务器端 UDP通信的实现 代码如下 已经很久没有在windows下编程了,这次因为需要做一个跨平台的网络程序,就先 ...

  4. Windows Phone下的Socket编程

    讨论下有关于Windows Phone下的Socket编程方面的知识. Socket就是通常所称的套接字,用于描述IP地址和端口,是一个通信链的句柄.应用程序通常通过Socket向网络发出请求或者应答 ...

  5. Windows环境下用C#编程将文件上传至阿里云OSS笔记

    Windows环境下用C#编程将文件上传至阿里云OSS笔记 本系列文章由ex_net(张建波)编写,转载请注明出处. http://blog.csdn.net/ex_net/article/detai ...

  6. Qt4.8在Windows下的三种编程环境搭建

    Qt4.8在Windows下的三种编程环境搭建 Qt的版本是按照不同的图形系统来划分的,目前分为四个版本:Win32版,适用于Windows平台:X11版,适合于使用了X系统的各种Linux和Unix ...

  7. windows下扩展yaf,并生成yaf框架文件

    YAF中文文档:http://www.laruence.com/manual/index.html 1 YAF框架是用C开发的,属于PHP的扩展框架: 2 YAF的性能相对于源生PHP,性能只降低不到 ...

  8. Windows内核开发-3-内核编程基础

    Windows内核开发-3-内核编程基础 这里会深入讲解kernel内核的API.结构体.和一些定义.考察代码在内核驱动中运行的机制.最后把所有知识合在一起写一个有用的驱动. 本章学习要点: 1:通用 ...

  9. Windows内核开发-4-内核编程基础

    Windows内核开发-4-内核编程基础 这里会构建一个简单但是完整的驱动程序和一个客户端,部署内核执行一些平时user下无法执行的操作. 将通过以下内容进行讲解: 1 介绍 2 驱动初始化 3 Cr ...

随机推荐

  1. 【分享】iTOP4412开发板-Bluetooth移植文档

    [分享]iTOP4412开发板-Bluetooth移植文档 最近须要把Bluetooth移植到iTOP-4412 开发平台.查阅了相关资料,经过一段时间的研究.调试,最终成功的将蓝牙功能移植到了开发板 ...

  2. cocos2dx中关于Action动作的相关API的具体介绍

     //CCMoveBy  创建一个移动的动作 //參数1:移动到目标坐标所需的时间 //參数2:目标坐标 //支持reverse 能够获取其反向动作 //CCMoveTo  一样的 //CCAct ...

  3. php&&页面静态化

    页面静态化.主要是出于两个方面的考虑.     第一:訪问html页面的速度比訪问php页面的速度快.在訪问php页面时候.须要对php进行解析.訪问html时候,直接浏览器能够解析出来.特别是PV量 ...

  4. adb连接手机报错解决方案汇总(win7)

    >>adb devices常见错误:   >>解决方案汇总 检查端口是否占用:netstat -ano | findstr 5037 | findstr LISTENING 检 ...

  5. android 使用Ksoap2工具类实现WebService网络编程

    1.下载Ksoap2,将jar包拷贝到libs目录下.然后右键点击拷贝进来的jar,在弹出菜单中点击Add As Library. 2.在AndroidManifest.xml中添加访问网络的权限 & ...

  6. 2017年国内常用的公共NTP服务

    安卓机顶盒里常用的 http://cn.pool.ntp.org CERNET 的一堆服务器就在那里面 http://asia.pool.ntp.org 追踪它的IP,台湾.韩国.日本都有. 阿里云 ...

  7. JavaScript中函数function fun(){}和 var fun=function(){}的区别

    function fun(){} 和 var fun=function(){}的区别 标题有点长···· 废话少说,其实他们的主要区别就是"函数声明的提前行为". var fun= ...

  8. 多命令顺序执行,dd命令,管道|,grep,通配符,其他特殊符号

    多命令顺序执行:命令1;命令2 命令之间没有逻辑关系 命令1&&命令2 命令1执行正确才执行命令2,命令1执行错误不会执行命令2 命令1||命令2 命令执行错误才执行命令2,命令1执行 ...

  9. JaveScript运算符(JS知识点归纳三)

    JaveScript中有许多的运算符,在这里就只说明一些需要注意的. 01 一元运算符 一元:指的是参与运算的操作数只有一个 最经常使用的是++   -- 计算规则: ++/-- 前置于操作数的时候 ...

  10. Parallels Desktop 12 for Mac 破解版

    Parallels Desktop for Mac 是功能最强大灵活度最高的虚拟化方案,无需重启即可在同一台电脑上随时访问Windows和Mac两个系统上的众多应用程序.从仅限于PC的游戏到生产力软件 ...