您的位置:首页 > 其它

软件调试笔记37 - 堆和堆检查 : 堆概览

2017-12-06 12:35 393 查看
内存是软件工作的舞台,当用户启动一个程序时,系统会将程序文件从外部存储器加载到内存中,当程序工作时,需要使用内存空间来放代码和数据。在使用一段内存之前,程序需要以某种方式比如库函数或API发出申请,接收到申请的一方比如C运行库或者各种内存管理器根据申请者的要求从可用空间中寻找满足要求的内存区域分配给申请者。当程序不再需要的时候,通过申请方式相对应的方法归还该空间,即释放。

堆是组织内存的另一种重要方法,是程序在运行期动态申请内存空间的主要途径。与栈空间是编译器产生的代码自动分配和释放不同(称之为“自动内存”),堆上的空间需要程序员编写代码来申请和释放。

栈上分配内存的不足

1. 容量相对较小,不适合特别大的内存区

2. 栈上的变量只是在函数内有效,不适合较长生存期的全局变量和对象

3. 尽管可以使用_alloca()从栈上分配可变长度的缓冲区,但是还是会给异常处理带来麻烦,因此不适合分配运行期才能决定大小的缓冲区。

堆克服了以上局限。



从操作系统的角度,堆是系统内存管理功能向应用软件提供服务的一种方式。通过堆,内存管理器将一块较大的内存空间委托给堆管理器来管理。堆管理器将大块的内存分割成不同大小的多个小块来满足应用程序的需要。应用程序的内存需求通常是频繁和零散的,如果把这些请求都传递给内存管理器就会影响系统的性能。有了堆管理器,内存管理器只需要处理大规模的分配请求,大大缩短了应用程序申请内存分配所需的时间,提高软件的运行速度。

多级内存分配体系

下图是内存分配体系。用户态的代码应该调用虚拟内存分配API来从内存管理器分配内存。虚拟内存API包括VirtualAlloc,VirualAllocEx,VirtualFree等。内核态的代码可以调用以上API对应的内核函数,比如NtAllocateVirtualMemory等。





与池管理器类似,在NTDLL.DLL中实现了一个通用的堆管理器,目的是为用户态的程序提供内存服务,称为Win32堆管理器。SDK中公开了一组API来访问WIN32堆管理器的功能,比如HeapAlloc, HeapFree等。



应用程序开发商也可以实现自己的堆管理器,只要通过虚拟内存API从内存管理器批发内存过来后提供给自己的客户代码使用。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: