查看单个帖子
旧 2007-05-14, 03:12 PM   #10
yogy
高级会员
 
注册日期: 06-11
帖子: 1527
精华: 15
现金: 6353 标准币
资产: 6353 标准币
yogy 向着好的方向发展
默认 回复: 【转帖】stack与heap的不同之处

什么是堆?
(如果您已经知道什么是堆,可以跳到什么是常见的堆性能问题?部分)
在程序中,使用堆来动态分配和释放对象。在下列情况下,调用堆操作:

事先不知道程序所需对象的数量和大小。
对象太大而不适合堆栈分配程序。

堆使用了在运行时分配给代码和堆栈的内存之外的部分内存。下图给出了堆分配程序的不同层。
http://www.microsoft.com/china/msdn...mages/heap3.gif
GlobalAlloc/GlobalFree
Microsoft Win32 堆调用,这些调用直接与每个进程的默认堆进行对话。
LocalAlloc/LocalFree
Win32 堆调用(为了与 Microsoft Windows NT 兼容),这些调用直接与每个进程的默认堆进行对话。
COM
IMalloc 分配程序(或 CoTaskMemAlloc / CoTaskMemFree):函数使用每个进程的默认堆。自动化程序使用组件对象模型 (COM)”的分配程序,而申请的程序使用每个进程堆。

C/C++
运行时 (CRT) 分配程序:提供了 malloc() free() 以及 new
delete
操作符。如 Microsoft Visual Basic Java 等语言也提供了新的操作符并使用垃圾收集来代替堆。CRT 创建自己的私有堆,驻留在 Win32 堆的顶部。

Windows NT
中,Win32 堆是 Windows NT 运行时分配程序周围的薄层。所有
API
转发它们的请求给 NTDLL
Windows NT
运行时分配程序提供 Windows NT 内的核心堆分配程序。它由具有128 个大小从 8 1,024 字节的空闲列表的前端分配程序组成。后端分配程序使用虚拟内存来保留和提交页。
在图表的底部是虚拟内存分配程序,操作系统使用它来保留和提交页。所有分配程序使用虚拟内存进行数据的存取。
分配和释放块不就那么简单吗?为何花费这么长时间?
堆实现的注意事项
传统上,操作系统和运行时库是与堆的实现共存的。在一个进程的开始,操作系统创建一个默认堆,叫做进程堆。如果没有其他堆可使用,则块的分配使用进程堆。语言运行时也能在进程内创建单独的堆。(例如,C 运行时创建它自己的堆。)除这些专用的堆外,应用程序或许多已载入的动态链接库 (DLL) 之一可以创建和使用单独的堆。Win32 提供一整套 API 来创建和使用私有堆。有关堆函数(英文)的详尽指导,请参见 MSDN
当应用程序或 DLL 创建私有堆时,这些堆存在于进程空间,并且在进程内是可访问的。从给定堆分配的数据将在同一个堆上释放。(不能从一个堆分配而在另一个堆释放。)
在所有虚拟内存系统中,堆驻留在操作系统的虚拟内存管理器的顶部。语言运行时堆也驻留在虚拟内存顶部。某些情况下,这些堆是操作系统堆中的层,而语言运行时堆则通过大块的分配来执行自己的内存管理。不使用操作系统堆,而使用虚拟内存函数更利于堆的分配和块的使用。
典型的堆实现由前、后端分配程序组成。前端分配程序维持固定大小块的空闲列表。对于一次分配调用,堆尝试从前端列表找到一个自由块。如果失败,堆被迫从后端(保留和提交虚拟内存)分配一个大块来满足请求。通用的实现有每块分配的开销,这将耗费执行周期,也减少了可使用的存储空间。
yogy离线中   回复时引用此帖