在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. 泛泰A870(高通APQ8064t 600 cpu) Mokee4.4.2(Android4.4) 图赏

    watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvc3lob3N0/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/d ...

  2. java泛型学习(一)

    泛型也叫做参数化类型,顾名思义的去理解,就是把类型作为一个参数.类比方法的传参,我们举个例子. class A{ public void getX(int x){ System.out.println ...

  3. Activiti 6.0 之SkipExpression

    Activiti 6.0 之SkipExpression 惭愧惭愧,这么一个小小的功能整了这么久. ​ 还是先说一下业务场景吧.在工作流中,我们难免会遇到这样的情况,即一个流程的发起者的身份问题.举个 ...

  4. 安装Oracle之后在DOS命令下不能使用sqlplus命令启动Oracle?

    就像完成安装JDK后需要给系统配置环境变量JAVA_HOME和PATH,以便让系统认识在JDK里面的Javac命令.同样的,安装Oracle也需要这么一个过程.在正常情况下安装Oracle时系统安装程 ...

  5. spring-boot学习笔记之Conditional

    今天看了@Conditional,自己根据以下文章练了下,根据自己的理解操作的             转载出处:http://wiselyman.iteye.com/blog/2213054 17. ...

  6. sourceTree git 忽略指定文件

    按照如下步骤执行(终端命令) 1. git status modified: LovegoMall.xcworkspace/xcuserdata/Tiny.xcuserdatad/xcdebugger ...

  7. IOS学习5——属性与成员变量

    [转]iOS中属性与成员变量的区别 ios中属性修饰符的作用 1. 属性用property声明 2. 简而言之,对于目前的ios开发,属性和成员变量的区别,完全可以不管. 3. 这个是历史原因造成的. ...

  8. iOS 类似朋友圈的图片浏览器SDPhotoBrowser

    SDPhotoBrowser.Demo 1.在文件SDBrowserImageView.m中有用SDWebImage到网络加载图片 需要的注释去掉即可 #import "ViewContro ...

  9. KVO等具体实现步骤以及注意事项

    KVO是一种设计模式,名为观察者. addObserver:forKeyPath:options:context: 通知其他对象的方法,这个方法在NSObject中就已经申明了,也就是说任何继承自NS ...

  10. 基于CDH 5.9.1 搭建 Hive on Spark 及相关配置和调优

    Hive默认使用的计算框架是MapReduce,在我们使用Hive的时候通过写SQL语句,Hive会自动将SQL语句转化成MapReduce作业去执行,但是MapReduce的执行速度远差与Spark ...