首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

内存管理机制(详细介绍) (3)

内存管理机制(详细介绍) (3)

如前所说,这是在堆栈区域0x0004 0000里分配的,后分配的地址arrayB反而更小,符合堆栈的特性。arrayA和arrayB它们处于不同的页面。页面都受页文件支持,并且区域都是提交的,是系统在线程创建时提交的。

·        C++动态分配了两次内存,一次是1K大一点,一个是64K左右。所以应该不会在一个区域。
char *dynamicA=new char[1024];
            char *dynamicB=new char[65467];
            VirtualQuery(dynamicA,&mbiA,len);
            cout<<"动态内存地址属性:"<<endl;
            cout<<"区域基地址="<<mbiA.AllocationBase<<endl;
            cout<<"区域邻近页面状态="<<mbiA.State<<endl;
            cout<<"区域保护属性="<<mbiA.AllocationProtect<<endl;
            cout<<"页面基地址="<<mbiA.BaseAddress<<endl;
            printf("dynamicA指针地址=%x\n",dynamicA);
            cout<<"从页面基地址开始的大小="<<mbiA.RegionSize<<endl;
            cout<<"邻近页面物理存储器类型="<<mbiA.Type<<endl;
            cout<<"页面保护属性="<<mbiA.Protect<<endl<<endl;

            VirtualQuery(dynamicB,&mbiB,len);
            cout<<"动态内存地址属性:"<<endl;
            cout<<"区域基地址="<<mbiB.AllocationBase<<endl;
            cout<<"区域邻近页面状态="<<mbiB.State<<endl;
            cout<<"区域保护属性="<<mbiB.AllocationProtect<<endl;
            cout<<"页面基地址="<<mbiB.BaseAddress<<endl;
            printf("dynamicB指针地址=%x\n",dynamicB);
            cout<<"从页面基地址开始的大小="<<mbiB.RegionSize<<endl;
            cout<<"邻近页面物理存储器类型="<<mbiB.Type<<endl;
            cout<<"页面保护属性="<<mbiB.Protect<<endl;

结果如下:


这里是动态分配,dynamicA和dynamicB处于两个不同的区域;同样,页面都受页文件支持,并且区域都是提交的。
第二个区域是比64K大的,由分配粒度可知,区域至少是128K。那么,剩下的空间也是提交的吗,如果是的话那就太浪费了。看看就知道了:0x00E2 1000肯定在这个空间里,所以查询如下:
VirtualQuery((char*)0xE23390,&mbiB,len);
            cout<<"动态内存地址属性:"<<endl;
            cout<<"区域基地址="<<mbiB.AllocationBase<<endl;
            cout<<"区域邻近页面状态="<<mbiB.State<<endl;
            cout<<"区域保护属性="<<mbiB.AllocationProtect<<endl;
            cout<<"页面基地址="<<mbiB.BaseAddress<<endl;
            printf("dynamicB指针地址=%x\n",0xE21000);
            cout<<"从页面基地址开始的大小="<<mbiB.RegionSize<<endl;
            cout<<"邻近页面物理存储器类型="<<mbiB.Type<<endl;
   cout<<"页面保护属性="<<mbiB.Protect<<endl;
结果如下:

可以看出,邻近页面状态为保留,还没提交,预料之中;0x00E1 0000 这个区域的大小可以计算出来:69632+978944=1024K。系统动态分配了1M的空间,就为了64K左右大小的空间。可能是为了使得下次有要求分配时时不用再分配了。

(三):虚拟内存3.      内存管理机制--虚拟内存 (VM)
·        虚拟内存使用场合
虚拟内存最适合用来管理大型对象或数据结构。比如说,电子表格程序,有很多单元格,但是也许大多数的单元格是没有数据的,用不着分配空间。也许,你会想到用动态链表,但是访问又没有数组快。定义二维数组,就会浪费很多空间。
它的优点是同时具有数组的快速和链表的小空间的优点。

·        分配虚拟内存
如果你程序需要大块内存,你可以先保留内存,需要的时候再提交物理存储器。在需要的时候再提交才能有效的利用内存。一般来说,如果需要内存大于1M,用虚拟内存比较好。

·        保留
用以下Windows 函数保留内存块
VirtualAlloc (PVOID 开始地址,SIZE_T 大小,DWORD 类型,DWORD 保护属性)
一般情况下,你不需要指定“开始地址”,因为你不知道进程的那段空间是不是已经被占用了;所以你可以用NULL。“大小”是你需要的内存字节;“类型”有MEM_RESERVE(保留)、MEM_RELEASE(释放)和MEM_COMMIT(提交)。“保护属性”在前面章节有详细介绍,只能用前六种属性。
如果你要保留的是长久不会释放的内存区,就保留在较高的空间区域,这样不会产生碎片。用这个类型标志可以达到:
MEM_RESERVE|MEM_TOP_DOWN。
C++程序:保留1G的空间
LPVOID pV=VirtualAlloc(NULL,1000*1024*1024,MEM_RESERVE|MEM_TOP_DOWN,PAGE_READWRITE);
            if(pV==NULL)
            cout<<"没有那么多虚拟空间!"<<endl;
            MEMORYSTATUS memStatusVirtual1;
            GlobalMemoryStatus(&memStatusVirtual1);
            cout<<"虚拟内存分配:"<<endl;
            printf("指针地址=%x\n",pV);
cout<<"减少物理内存="<<memStatusVirtual.dwAvailPhys-memStatusVirtual1.dwAvailPhys<<endl;
cout<<"减少可用页文件="<<memStatusVirtual.dwAvailPageFile-memStatusVirtual1.dwAvailPageFile<<endl;
cout<<"减少可用进程空间="
<<memStatusVirtual.dwAvailVirtual-memStatusVirtual1.dwAvailVirtual<<endl<<endl;
继承事业,薪火相传
返回列表