内存管理

来源:互联网 发布:电信网络电视光纤猫 编辑:程序博客网 时间:2024/04/30 03:29

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.

ValueDescriptionMEM_RESERVEReserve 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_COMMITCommit 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.

ValueDescriptionMEM_DECOMMITDecommit memory of size cbSize from pAddr.MEM_RELEASERelease 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);
原创粉丝点击