动态内存分配指的是在堆上进行分配内存,根据申请分配的层次可以分成两大类:
1、底层:堆内存管理函数HeapCreate、HeapAlloc、HeapFree、HeapDestroy函数
HeapCreate函数功能:创建自定义堆,这不同与默认堆由进程创建时系统自动创建。HeapAlloc函数功能:从自定义堆中分配内存。HeapFree函数功能:释放内存。但并不能保证所有的物理内存都被释放,系统会根据物理内存页面大小判断是否释放回收,同时也从效率上考虑不会马上释放。HeapDestroy函数功能:堆销毁。堆分配的内存全部释放回收。如果没有显式调用它,则在进程退出时,系统做销毁的工作。如果是线程创建的,则不会随线程退出而释放,好找习惯是要进行手工释放。不要等到进程结束时让系统来做。这样能提高资源利用率。
还有其它函数,如:GetProcessHeaps函数:获取进程所有的堆。HeapReAlloc函数:修改分配内存的大小。HeapSize函数:查询某块分配内存的大小。HeapCompact函数:将相邻的回收内存块合并一起。
这些函数组合可进行自定义堆内存的分配,它们可以减少内存碎片,节省空间。这些内存块通常用来处理某种特定的数据结构,访问相邻数据的时间紧凑,大大减少引起的缺页错误。HeapCreate函数还可以关闭线程同步访问功能,以获取程序性能上的提升。
可以看一下windows 2000下的HeapAlloc函数代码:
void
NEAR* NEAR HeapAlloc(HHEAP hhp,
WORD
cb)
{
void
NEAR* pb;
_asm {
push ds
mov ds,hhp
}
pb = (
void
NEAR*)LocalAlloc(LMEM_FIXED | LMEM_ZEROINIT, cb);
if
(pb)
((HEAP NEAR*)0)->cAlloc++;
_asm {
pop ds
}
return
pb;
}
2、上层:malloc/free函数和new/delete操作符
malloc/free是C语言中的分配内存函数,与操作系统无关,C++继承了这个函数,另外又提供了new/delete操作符,它们都是通过操作系统的内存管理机制实现内存管理的。为了申请内存,它们通过一定的算法在堆内存中搜索可用的内存,如果是由于内存碎片太多而造成的空间不够,它们会调用内核相应的方法增加程序数据段的存储空间,以获取合适的内存空间,相比于栈来说,它们的效率较低。这种效率低下体现在:申请内存中它们不可以直接提交,释放内存时又不可以直接回收物理内存。
可以看一下windows 2000下的malloc函数代码:
void
* __cdecl
malloc
(
size_t
sz
)
{
return
RtlAllocateHeap( RtlProcessHeap(), 0, sz );
}
这里面的函数内部会调用HeapAlloc函数的。从这方面来看,malloc效率不能与HeapAllo相比。另外对于new来说效率还不如malloc,在windows操作系统下是按照:
new->malloc->HeapAlloc->VirtualAlloc->驱动程序的_PageAlloc这个顺序调用的。
关于详细的内存管理函数说明可参考:
https://msdn.microsoft.com/en-us/library/aa366597(v=vs.85).aspx