内存管理-堆

 

 

windows32位下,每个进程都有自己独立的4G内存空间,高2G是操作系统内核使用,低2G是供用户使用。

每个进程中使用的都是虚拟地址,虚拟机地址到物理地址的转换由操作系统完成,所以我们无法在自己的进程当中访问其他进程的内存。

对于不同的进程Windows尽量保证同一份数据,在物理内存中只有一份,再分别映射到多个进程中,达到节约内存的目的。

当各个进程所使用的内存数量超出物理内存大小的时候,操作系统还能将物理内存中暂时用不到的数据交换到硬盘中。

Windows如何管理内存数据

Windows提高了三种方式来管理内存数据

适用于管理大量的小型对象,使用堆管理方式可以非常方便的帮我们管理所需要的内存空间,缺点是效率低,控制不够灵活

虚拟内存

适用于管理大型的对象数组或大型的结构数组,使用虚拟内存管理方式有丰富的内存管理接口,可以使我们更加精确的控制内存数据

文件映射

适用于管理大型的数据流,以及在同一个机器上的不同的进程间共享数据。

堆在Windows中是作为一个对象来管理的,我们可以创建一个堆对象,之后在堆上分配内存,销毁内存等,C/C++中的new和malloc其实也是使用Windows中的堆对象来分配空间

当Windows系统创建一个进程后,会为此进程创建一个默认的堆,这个默认堆是不能够被销毁的。

堆内存管理相关API

HeapCreate在进程中创建一个堆对象,返回一个句柄
GetProcessHeap 获取当前进程中的一个堆,返回一个句柄
GetProcessHeaps 获取进程中的所有堆
HeapAlloc 从指定堆上分配内存
HeapReAlloc 重新分配内存,改变已经分配好的堆的内存大小
HeapSize 获取堆的大小
HeapDestroy 销毁堆对象,不能销毁进程中默认创建的堆对象
HeapFree 释放掉对应HeapAlloc分配的内存

创建一个堆

HANDLE HeapCreate(
DWORD flOptions,
SIZE_T dwInitialSize,
SIZE_T dwMaximumSize
);

flOptions表示堆的后序选项,dwInitalSize表示堆的初始值,dwMaximumSize表示堆的最大大小

//例子
HANDLE hHeap = HeapCreate(0,0,0);

分配堆内存

DECLSPEC_ALLOCATOR LPVOID HeapAlloc(
HANDLE hHeap,
DWORD dwFlags,
SIZE_T dwBytes
);

成功就会返回堆的分配内存块的地址

堆的Windows API使用例子

#include<Windows.h>
#include<iostream>
using namespace std;

int main()
{
//1 创建一个堆对象
HANDLE hHeap = HeapCreate(0,0,0);
//2 申请堆内存
char * str = (char*)HeapAlloc(hHeap, HEAP_ZERO_MEMORY, 0);
//3 给内存赋值
strcpy_s(str, 10, "hellowor");
cout << str << endl;
//4 释放申请的堆内存
HeapFree(hHeap, 0, str);
//5 摧毁堆对象
HeapDestroy(hHeap);
return 0;
}