1.关于虚拟内存:主要优点:应用程序与设备物理地址的实现无关。
分页式内存:每页大小4kb。
虚拟页面有3种状态:空闲(free)、保留(reserved)、提交(committed)。
2.系统内存查询:GetSysemInfo、GlobalMemoryStatus、GetStoreInformation。
3.WinCE应用程序有很多不同的内存分配方法。在内存管理食物链的底部是VirtualXXX函数,他们直接保留、提交和释放虚拟内存页。接下来是堆API。堆是系统为应用程序管理的已保留的内存空间区域。堆有两种形式:当应用程序启动时默认自动分配的本地堆,以及可由应用程序手动创建的堆。在堆API之后是静态数据--由编译器定义并且由装载器自动分配的数据块。最后才轮到栈,它是应用程序存储函数中局部变量的地方。
4. 虚拟内存:系统调用虚拟内存API来为包括堆和栈这样的其他类型的内存分配内存。虚拟内存API包括:VirtualAllo、VirtualFree、VirtualResize,直接操作应用程序的虚拟内存空间中的虚拟内存页面。使用这些函数可以保留页面,将页面提交给物理内存和释放页面。
1)分配虚拟内存:LPVOID VirtualAllo();
2)释放虚拟内存:回收页面将是页面不映射到RAM中的物理页面,但仍保留该页面被保留的状态。BOOL VirtualFree();
该函数用来回收或释放内存。如果区域被回收,则参数dwSize指明该区域的大小,以字节为单位;如果要释放该区域,则这个值必须是0。
通过virtualFress释放的区域中的所有页面必须处于同一种状态。也就是说,区域中将被释放的所有页面必须全部被提交或全部被保留。要释放既有被保留的页面又有被提交的页面的区域,则应该首先回收提交的页面,然后释放整个区域。
//这段代码将分配512块单页的虚拟内存:先保留一块区域,然后再提交页面。
pMemBase = VirtualAlloc(NULL,PAGESIZE *512,MEM_RESERVE,PAGE_NOACCESS);
for(i = 0;i<512;i++)
pMem[i] = VirtualAlloc(pMemBase+(i*PAGESIZE),PAGESIZE,MEM_COMMET,PAGE_READWRITE);
3)通过调用VirtualProtect()函数可以更改最初在VirtualAlloc()中指定的虚拟内存的访问权限。这个函数只能更改已提交页面的访问权限。
4)查询当前的某个区域的保护权限:VirtualQuery();
5)wince6 起,操作系统开始支持桌面版本中扩展的虚拟内存API,这些函数运行一个应用程序操作另一个应用程序的内存地址空间。
VirtualAllocEx(),VirtualFreeEx(),VirtualQueryEx(),
VirtualProtectEx();
5. 堆:虚拟内存以页为单位分配内存是低效的,要优化内存的使用,应用程序必须能以字节、或至少32字节为基础来分配和释放内存。系统运行通过堆来实现这种大小的内存分配。
当应用程序启动时,每个应用程序都有一个由系统创建的默认堆或本地堆。你可以使用函数LocalAlloc,LocalFress,LocalRealloc来分配、释放、调整本地堆中内存块的大小。应用程序也可以创建任意数量的独立堆。这些堆与本地堆具有相同的属性,不过是通过一组单独的Heapxxxx函数来管理。
本地堆:1)分配本地堆中的内存;LocalAlloc();
2)释放本地堆中的内存;LocalFree();
3)调整和查询本地堆内存的大小;LocalReAlloc();
4)查询块的大小;LocalSize();
独立堆:如果你需要分配一系列内存块并使用一段时间,最好能避免这些分配把本地堆分割成碎片,更好的办法就是创建一个独立堆。
1)创建独立堆;HeapCreate();
在默认情况下,Windows堆管理例程将阻止同一个进程中的两个线程同时访问堆。这种串行化可以可以防止系统用来跟踪对中已分配的堆指针被破坏。
2)在独立堆中分配内存;HeapAlloc();
总是分配固定大小的内存块。
3)释放独立堆中的内存;HeapFree();
4)调整和查询独立堆中的内存大小;HeapReAlloc()
5)确定快的实际大小可以调用函数HeapSize();
6)销毁独立堆;HeapDestory();
在你销毁堆之前,不必释放堆中单独的块。
7)有时候有些应用程序需要控制堆使用的内存的类型和位置。WinCE有一个特殊的函数,可以告诉堆管理器当堆需要分配、提交或释放虚拟内存时,回调应用程序指定的函数。这个函数是:
HANDLE CeHeapCreate();
当堆管理器需要更多的虚拟内存来满足分配请求时,会回调参数pfnAlloc所指向的函数。函数原型:
This function is a custom allocator function for heaps.
typedef LPVOID (*PFN_AllocHeapMem)( LPVOID pAddr, DWORD cbSize, DWORD fdwAction, LPDWORD pdwUserData );
Parameters
-
pAddr
- [in] Address to allocate memory; always page-aligned. cbSize
- [in] Size of the allocation. fdwAction
-
[in] Value that specifies the action.
The following table shows values for this parameter.
Value Description MEM_RESERVE Reserve memory of size cbSize. The pAddr parameter is a hint that it can be passed directly to the VirtualAlloc function or the allocator can ignore it.
MEM_COMMIT Commit cbSize bytes of memory from pAddr.
pdwUserData
- [in] A DWORD associated with each memory reservation, which can be used by the allocator to store information.
Return Value
A pointer to the memory allocated indicates success.
NULL indicates failure.
Requirements
OS Versions: Windows CE 5.0 and later.
Header: Developer-defined.
Link Library: Coredll.lib.
该回调函数干什么取决于它的第三个参数fdwAction。这个参数可以为MEM_RESERVE ,MEM_COMMIT之一。如果是前者,pAddr的值是0,并且cbSize包含了要保留的内存的总量。pdwUserData参数指向一个由应用程序定义的值,该值可以用于任何目的。当保留的区域被提交或稍后被释放时,这个用户自定义数据被传回应用程序。
当这个函数被用来提交内存时,参数pAddr指向要提交的保留内存。cbSize参数提供要提交区域的大小,pdwUserData参数指向在保留回调过程中的所设定的值。不管是保留还是提交,该回调函数的返回值应是指向要保留的内存或要提交的内存的指针。
当堆管理器需要回收或释放与堆有关的内存页面时,会回调CeHeapCreate函数中的pfnFree参数所指向的函数。
This function is a custom deallocator function for heaps
Parameters
-
pAddr
- [in] Memory address to be freed; always page-aligned. cbSize
- [in] Size to be freed or 0 if MEM_RELEASE is specified. fdwAction
-
Value that specifies the action.
The following table shows values for this parameter.
Value Description MEM_DECOMMIT Decommit memory of size cbSize from pAddr. MEM_RELEASE Release the whole memory reservation. cbSize will be 0.
dwUserData
- [in] A DWORD associated with the memory reservation.
Return Value
A nonzero value indicates success; zero indicates failure.
当堆管理器要回收RAM 页面时,调用会传入MEM_DECOMMIT,而MEM_FREE用于在要释放保留的虚拟内存区域时。dwUserData的值是在回调应用程序指定的分配回调函数时指定的值,当时分配的块正是现在将要释放或回收的块。
6.栈;WinCE中的栈是用来存放函数中使用的局部变量的。操作系统也用栈来存储函数的返回地址,以及在异常处理中存储微处理器寄存器的状态。
WinCE为系统中的每个线程提供一个单独的栈。默认情况下,系统中每个栈的最大容量都被限制为56kb。一个进程中每个单独的线程都可以增加自己的栈,直到56kb。当创建一个线程时,系统保留一个64kb区域用于该线程的栈,56kb的限制来自于栈所占用的64kb区域减去包含栈免于上溢和下溢所必须的两个页。
当应用程序创建第二个线程时,栈的对打尺寸可以通过创建线程时的CreateThread函数参数来指定。最大可以设为进程中空闲的虚拟内存空间的大小。**默认栈的大小也是所有单独线程栈的默认栈大小。也就是说,如果你把主线程的栈设为128kb,那么应用程序中所有线程的栈默认都是128kb大小,除非你使用CreateThread创建线程时指定了一个不同的大小。
typedef BOOL (*PFN_FreeHeapMem)( LPVOID pAddr, DWORD cbSize, DWORD fdwAction, DWORD dwUserData );