转载:Windows CE内存管理
wProcessorArchitecture参数表示系统微处理器的架构。它的值是定义在Winnt.h中,例如PROCESSOR_ARCHITECTURE_INTEL。Windows CE扩展了这些常数,包括PROCESSOR_ARCHITECTURE_ARM,PROCESSOR_ARCHITECTURE_SHx,等等。增加的常数包括像Win32操作系统支持的网络CPU(net CPU)。跳过一些参数,我们看dwProcessorType参数,它来自于特定的微处理器类型。常数有Hitachi SHx架构中的PROCESSOR_HITACHI_SH3和PROCESSOR_HITACHI_SH4。最后两个参数,wProcessorLevel和wProcessorRevision,指明了CPU类型的特征。wProcessorLevel参数类似于dwProcessorType参数,它一个指定的微处理器系列中被定义了,dwProcessorRevision告诉你模式(model)和芯片的步进级别(stepping level)。
typedef struct {
WORD wProcessorArchitecture;
WORD wReserved;
DWORD dwPageSize;
LPVOID lpMinimumApplicationAddress;
LPVOID lpMaximumApplicationAddress;
DWORD dwActiveProcessorMask;
DWORD dwNumberOfProcessors;
DWORD dwProcessorType;
DWORD dwAllocationGranularity;
WORD wProcessorLevel;
WORD wProcessorRevision;
} SYSTEM_INFO;
|
它返回一个MEMORYSTATUS结构,定义为
typedef struct {
DWORD dwLength;
DWORD dwMemoryLoad;
DWORD dwTotalPhys;
DWORD dwAvailPhys;
DWORD dwTotalPageFile;
DWORD dwAvailPageFile;
DWORD dwTotalVirtual;
DWORD dwAvailVirtual;
} MEMORYSTATUS;
|
dwLength参数在调用这个函数之前必须初始化。dwMemoryLoad参数是一个不确定的值;这是一个可用的一般性的参数指示了当前系统的内存使用情况(译者注:该参数是一个近似的百分比值,指明了物理内存的使用情况)。dwTotalPhys和dwAvailPhys参数指明了RAM有多少页被分配给了程序存储区RAM,和还有多少可用(译者注:实际上是以字节为单位)。这些值不包括分配对象存储区的RAM。
通过GlobalMemoryStatus返回的信息可以验证Windows CE内存结构,通过在有32MBRAM的HP iPaq Pocket PC上调用函数,返回值如下:
dwMemoryLoad 0x18 (24)
dwTotalPhys 0x011ac000 (18,530,304)
dwAvailPhys 0x00B66000 (11,952,128)
dwTotalPageFile 0
dwAvailPageFile 0
dwTotalVirtual 0x02000000 (33,554,432)
dwAvailVirtual 0x01e10000 (31,522,816)
|
分配和保留虚拟内存是同过这个函数完成的:
LPVOID VirtualAlloc (LPVOID lpAddress, DWORD dwSize,
DWORD flAllocationType,
DWORD flProtect);
|
VirtualAlloc 的第一个参数是要分配内存区域的地址。当你使用VirtualAlloc来提交一块以前保留的内存块的时候,lpAddress参数可以用来识别以前保留的内存块。如果这个参数是NULL,系统将会决定分配内存区域的位置,并且围绕64-KB的范围(译者注:就是前面说提及的最小内存分配尺寸)。第二个参数是dwSize,要分配或者保留的区域的大小。这个参数以字节为单位,而不是页,系统会根据这个大小一直分配到下页的边界。
因为对每个进程32MB虚拟内存地址空间的限制,这就有了一个最大值 32MB/64KB-1=511,这是虚拟内存在内存溢出前能被保留的最大值。接下来,有个例子,代码段如下:
#define PAGESIZE 1024 // Assume we're on a 1-KB page machine
for (i = 0; i < 512; i++)
pMem[i] = VirtualAlloc (NULL, PAGESIZE, MEM_RESERVE │ MEM_COMMIT,PAGE_READWRITE);
|
代码分配512个单页的虚拟内存。甚至你系统还有一半的可用RAM,VirtualAlloc也会在完成分配前失败。因为它的运行已经超出了应用程序的虚拟地址空间。发生这种情况是因为每1-KB的块要占用64-KB的空间,接下来应用程序的代码,栈,和本地堆也要映射到同样的32-MB虚拟地址空间,可用的虚拟分配区域通常不超过475个。
一个比较好的分配512块特殊内存的方法是这样做:
#define PAGESIZE 1024 // Assume we're on a 1-KB page machine.
// Reserve a region first.
pMemBase = VirtualAlloc (NULL, PAGESIZE * 512, MEM_RESERVE,
PAGE_NOACCESS);
for (i = 0; i < 512; i++)
pMem[i] = VirtualAlloc (pMemBase + (i*PAGESIZE), PAGESIZE,
MEM_COMMIT, PAGE_READWRITE);
|
代码首先保留了一块区域,页面将在以后被提交。因为区域已经被先保留了,提交页就不受64-KB限制(译者注:只有保留页最小值受64KB限制),等等,如果你系统中有512KB的可用内存,分配将会成功。
你可以通过调用VirtualFree来取消提交,或释放虚拟内存。从物理RAM页中取消提交或者取消映射,但是保持页被保留的状态。函数原型如下:
BOOL VirtualFree (LPVOID lpAddress, DWORD dwSize,
DWORD dwFreeType); |
lpAddress参数是一个指针,指向要被释放或取消提交的虚拟内存的区域。dwSize参数指明要取消提交区域的大小,以字节为单位。如果区域要被释放,这个值必须是0,dwFreeType参数包含了操作类型标志,MEM_DECOMMIT标志指定了区域将被取消提交但是仍被保留,MEM_RELEASE标志说明区域要取消提交并且释放。
PMEMORY_BASIC_INFORMATION结构被定义如下:
typedef struct _MEMORY_BASIC_INFORMATION {
PVOID BaseAddress;
PVOID AllocationBase;
DWORD AllocationProtect;
DWORD RegionSize;
DWORD State;
DWORD Protect;
DWORD Type;
} MEMORY_BASIC_INFORMATION;
|
MEMORY_BASIC_INFORMATION 结构的第一个字段是BaseAddress,是传递给VirtualQuery函数的一个地址。AllocationBase字段包含使用 VirtualAlloc函数分配的区域的基地址,AllocationProtect字段包含区域原来被分配时的保护属性。RegionSize字段包含从传递给VirtualQuery的指针开始到一系列具有相同属性的页为结尾的区域大小(译者注:这里是从基地址开始)。State字段包含区域中页的状态-自由,保留,提交。Protect字段可以包含MEM_PRIVATE标志,指明该区域包含应用程序私有的数据;MEM_MAPPED指明该区域被映射为一个内存映射文件;MEM_IMAGE指明该区域被映射为一个EXE或DLL模块。
如果一个对VirtualQuery的调用中,lpAddress指向第四页的区域(地址0xA1000),返回值如下:
BaseAddress 0xA1000
AllocationBase 0xA0000
AllocationProtect PAGE_NOACCESS
RegionSize 0x1C00 (7,168 bytes or 7 pages)
State MEM_COMMIT
Protect PAGE_READWRITE
Type MEM_PRIVATE
|
BaseAddress 字段包含传递给VirtualQuery的地址,值为0xA1000,在最初的区域中是第4096字节。AllocationBase字段包含最初区域的地址。当AllocationProtect设为PAGE_NOACCESS时,指明区域是最初被保留的,而不是直接提交。RegionSize字段包含传递给VirtualQuery的指针0xA1000开始,到被提交的页结束地址0xA2C00的字节数。State和Protect字段包含的标志表明当前的页状态。Type字节表明区域被应用程序分配给自己使用。
LPVOID HeapReAlloc (HANDLE hHeap, DWORD dwFlags, LPVOID lpMem,
列表7-1。映象文件的顶部显示了应用程序数据段的大小
memtest Timestamp is 34ce4088 (Tue Jan 27 12:16:08 1998) Preferred load address is 00010000 Start Length Name Class 0001:00000000 00006100H .text CODE 0002:00000000 00000310H .rdata DATA 0002:00000310 00000014H .xdata DATA 0002:00000324 00000028H .idata$2 DATA 0002:0000034c 00000014H .idata$3 DATA 0002:00000360 000000f4H .idata$4 DATA 0002:00000454 000003eeH .idata$6 DATA 0002:00000842 00000000H .edata DATA 0003:00000000 000000f4H .idata$5 DATA 0003:000000f4 00000004H .CRT$XCA DATA 0003:000000f8 00000004H .CRT$XCZ DATA 0003:000000fc 00000004H .CRT$XIA DATA 0003:00000100 00000004H .CRT$XIZ DATA 0003:00000104 00000004H .CRT$XPA DATA 0003:00000108 00000004H .CRT$XPZ DATA 0003:0000010c 00000004H .CRT$XTA DATA 0003:00000110 00000004H .CRT$XTZ DATA 0003:00000114 000011e8H .data DATA 0003:000012fc 0000108cH .bss DATA 0004:00000000 000003e8H .pdata DATA 0005:00000000 000000f0H .rsrc$01 DATA 0005:000000f0 00000334H .rsrc$02 DATA Address Publics by Value Rva+Base Lib:Object 0001:00000000 _WinMain 00011000 f memtest.obj 0001:0000007c _InitApp 0001107c f memtest.obj 0001:000000d4 _InitInstance 000110d4 f memtest.obj 0001:00000164 _TermInstance 00011164 f memtest.obj 0001:00000248 _MainWndProc 00011248 f memtest.obj 0001:000002b0 _GetFixedEquiv 000112b0 f memtest.obj 0001:00000350 _DoCreateMain 00011350 f memtest.obj. |
在列表7-1中的映象文件指出了EXE文件有五个区。区0001是文本段,包含程序中可执行的代码。区0002包含只读(read-only)静态数据。区0003包含可读写(read/write)静态数据。区0004包含调用其他DLL的固定表。最后,区0005是资源区,包含应用程序的资源,例如菜单和对话框模板。
以.bss段为结尾。最后一个段.rdata,包含只读数据。你使用const关键字定义的静态数据结束在.rdata段。有一个结构的例子,使我用来作消息查询表的:
// Message dispatch table for MainWindowProc
const struct decodeUINT MainMessages[] = {
WM_CREATE, DoCreateMain,
WM_SIZE, DoSizeMain,
WM_COMMAND, DoCommandMain,
WM_DESTROY, DoDestroyMain,
};
|
事件
|
自由内存
1024-Page Size
|
自由内存
4096-Page Size
|
注解
|
Limited-memory state
|
128 KB
|
160 KB
|
发送 WM_HIBERNATE 消息给in reverse Z-order的应用程序。释放栈空间并回收利用。
|
Low-memory state
|
64 KB
|
96 KB
|
限制虚拟内存分配为16 KB。 显示Low-memory对话框。
|
Critical-memory state
|
16 KB
|
48 KB
|
限制虚拟内存分配为8KB。
|
事件
|
自由内存
1024-Page Size
|
自由内存
4096-Page Size
|
注解
|
Hibernate threshold
|
200 KB
|
224 KB
|
发送 WM_HIBERNATE 消息给in reverse Z-order的应用程序。
|
Limited-memory state
|
128 KB
|
160 KB
|
开始关闭在 reverse Z-order上的应用程序。释放栈空间并回收利用。
|
Low-memory state
|
64 KB
|
96 KB
|
限制虚拟内存分配为16 KB。
|
Critical-memory state
|
16 KB
|
48 KB
|
限制虚拟内存分配为8 KB。
|
转载:Windows CE内存管理相关推荐
- 面试题总结之windows/linux内存管理
前言 请说说你对windows/linux内存管理的认识 解答 内存管理的必要性 出现在早期的计算机系统当中,程序是直接运行在物理内存中,每一个程序都能直接访问物理地址.如果这个系统只运行一个程序的话 ...
- Windows的内存管理机制
Windows下的内存是如何管理的? Windows内存的管理可以分为两个层面:物理内存和虚拟内存 其中物理内存由系统管理,不允许应用程序直接访问,应用程序可见的只有一个2G的地址空间,而内存分配是通 ...
- 艾伟_转载:.NET内存管理、垃圾回收
1. Stack和Heap 每个线程对应一个stack,线程创建的时候CLR为其创建这个stack,stack主要作用是记录函数的执行情况.值类型变量(函数的参数.局部变量 等非成员变量)都分配在st ...
- 【转载】ogre内存管理
原文:ogre内存管理 OGRE内存分配策略相关文件及简述 OGRE提供了自己的内存分配策略,甚至为STL容器提供了新的分配策略,相关文件及简述如下: OgreMemoryAllocatedObjec ...
- Windows操作系统内存管理
线性地址管理 Windows x86 进程空间地址划分 空指针赋值区:0x00000000~0x0000FFFF 用户模式区:0x00010000~0x7FFEFFFF 64KB禁入区:0x7FFF0 ...
- Windows CE的电源管理
Windows CE的基本电源管理功能 在所有版本的Windows CE操作系统中,图形.视窗和事件子系统(GWES)在电源管理方面都发挥了关键作用.这是因为早期版本的电源管理功能是由用户的活动所驱动 ...
- Windows CE设备驱动开发之电源管理
4.7电源管理 电源管理模块管理设备电源,从而全面改进操作系统的电源使用效率:它所有设备的电源使用,同时能与不支持电源管理的应用程序及驱动程序共存. 使用电源管理可以有效的减少目标设备的电源消耗,同时 ...
- Windows CE的电源管理之三
本篇将以Windows Mobile为例介绍Windows CE电源管理的实现,大体上,Windows Mobile分为Pocket PC和Smartphone两种版本.这两者之间的主要区别在于触摸屏 ...
- 笔试题 遗忘点记录 面向对象特点 + 产生死锁条件+ windows内存管理方法
)单一职责原则.就一个类而言,应该仅有一个引起它变化的原因. //感觉这个是 低耦合 高内聚 (2)开放封闭原则.软件实体对外扩展开放,对修改封闭. ...
最新文章
- AJAX:Getting Started
- 树莓派hdmi输出没声音_树莓派 4 开箱记
- JavaScript随机排序算法1
- Nancy跨平台开发总结(六)三层架构之Token认证的Rest API
- 做数据中心,腾讯是认真的!
- c语言微信挑一挑编程,100行python代码实现微信跳一跳辅助程序
- markdown首行空两格
- 【leetcode】二叉树(python)
- 基于SSM的实验室预约系统
- 列表左右移动 2017-03-23
- 一文搞明白DNS与域名解析
- axios请求文件流下载文件
- 机器人卫士密码箱密码忘了怎么办_幼儿园来了“晨检”机器人卫士
- 台式计算机风扇一直响,为什么电脑风扇一直响
- 「水花投资」是什么?是个人吗?
- 论汽车车机快速启动与开机动画、倒车影像三者关系
- Part GeoAI----当ArcGIS遇上人工智能
- python爬取人人车网站数据
- 【Arduino】基于阿里云的体感手柄
- 软件危机产生的原因与表现及解决方法
热门文章
- SPField的几种name的释疑
- orcale实现自定义优先级排序的SQL
- java linux 串口_Linux Java 串口通信 | 学步园
- oracle导入报错39002,oracle impdp ORA-39002
- python开发多平台app_django下创建多个app并设置urls方法
- Special Permutation CodeForces - 1352G(构造)
- Destroying Array(并查集)
- Diversity HDU - 6725
- Codeforces Round #572 (Div. 2)(ABCD1D2E)
- matlab中方差直方图,如何规范直方图在MATLAB?