lgxqf  

第十五章 应用虚拟内存

1.在地址空间内保留一块区域(地址空间)

                LPVOID WINAPI VirtualAlloc(

                 __in          LPVOID lpAddress,//指定区域的首地址 (地址值为64KB的整数倍)

                 __in          SIZE_T dwSize,    //区域的大小(字节数) 4KB的整数倍

                 __in          DWORD flAllocationType,//分配方式:Reserve|Commit|Reset MEM_TOP_DOWN|MEM_LARGE_PAGES

                 __in          DWORD flProtect //设置保护属性

                );

 

                (1)lpAddressNULL, 系统会在进程空间中找到一块合适区域,然后将该区域的地址返回

                (2)若想指定区域的首地址, 则需将首地址的值赋给lpAddress

                                系统会自动将该值切割成64KB的整数倍,如:我们想在19,668,992 (300 × 65,536 + 8192)处保留一块区域

                                系统会把19,668,992切割成19,660,800 (300 × 65,536). 然后在该地址处保留一块区域并返回该值(19,660,800)

                (3) MEM_TOP_DOWN 在高地址处分配空间

                                lpAddressNULL,系统可能在进程空间的任意部分保留一块区域。若该区域是在进程的地址空间的中部,则有可能会产生内存碎片。

                                为了避免内存碎片的产生 尤其是当我们想常时间保留一块区域时,我们可以通过设定MEM_TOP_DOWN,让系统尽可能的在高地址处保留一块区域。

 

2.交付会把实际的物理存储空间分配给保留的区域。

                我们可以在保留一块区域的同时来交付这块区域。也可以先保留,等需要时再交付这块区域。

               

                当需要分配大量内存时,如果CPU支持“大分页分配”,可以用MEM_LARGE_PAGE GetLargePageMinimum来增加分页大小,提高分配内存的性能。

                在做大分页分配时有以下两点需要注意:

                (1)大分页分配的内存是unpageable的,只能存在于RAM中,不会存在Page file

                (2)用户必而具有Lock Memory的权限。

                更多信息查阅MSDN by keyword:Large Page Support

 

3.何时交付内存

                适时的交付内存可以提高内存的使用效率,避免分配不必要的内存导致内存资源浪费。

                判断何时分配内存的最好方法是SHE(Structured Exception Handling),详见第二十五章

 

4.解除交付和释放保留区域

Decommitting Physical Storage and Releasing a Region

 

              BOOL VirtualFree(

                              LPVOID pvAddress,

                              SIZE_T dwSize,

                              DWORD fdwFreeType

                              );

 

               (1)释放保留区域 release a region

                              当释放保留区域时,我们必须释放整个保留的区域,该交付给该区域会被释放掉。试图访问已释放的区域会导致异常。

               (2)解除交付

                              仅释放内存,但该区域仍处于保留状态。我们可以仅解除一部分区域而不必像“释放保留区域”那样解除整个区域

                              解除交付也是以分页为单位的。dwSize指定了要释放的大小(以字节为单位)

                              若大小不够一页按一页算。

                                              例:3KB,那么系统会解除交付 pvAddress~pvAddress+4KB空间内的内存。

                                                  5KB,那么系统会解除交付 pvAddress~pvAddress+8KB空间内的内存。

 

5改变保护属性

              BOOL VirtualProtect(

                              PVOID pvAddress,

                              SIZE_T dwSize,

                              DWORD flNewProtect,

                              PDWORD pflOldProtect

                              );

 

              我们在保留地址空间时要指定区域的保护的属性。

              通过VirtualProtect函数我们可以动态地改变区域中某些分页的保护属性

 

6.Reset物理存储的内容

 

              Reset的用途是告诉系统指定的区域的内容没有改变,不需要将该区域的内容写到页文件中。

              以便使这块区域长期存放在RAM,以便再用到该区域时不需要换页操作。

 

7.Common API:

              GetLargePageMinimum

 

posted on 2009-02-27 17:05  Justin_Ma  阅读(365)  评论(0编辑  收藏  举报