Windows API笔记(一)内核对象
Windows API笔记(二)进程和进程间通信、进程边界
Windows API笔记(三)线程和线程同步、线程局部存储
Windows API笔记(四)win32内存结构
Windows API笔记(五)虚拟内存
Windows API笔记(六)内存映射文件
Windows API笔记(七)堆
Windows API笔记(八)文件系统
Windows API笔记(九)窗口消息
Windows API笔记(十)动态链接库
Windows API笔记(十一)设备I/O
在Win32中操作内存的第3种方法是使用堆。堆非常适合于分配很多小块的数据。例如,使用堆来管理链表和树要比使用虚拟内存或内存映射文件好很多。
堆的特性:
- 堆是属于进程的,一个进程的堆种的内容不能被其他进程种的线程访问
- 在通常的程序中,很多数据默认存放在缺省堆,例如:new、malloc等申请的内存空间
- 堆是虚拟内存上的一种特殊内存管理方式
- dll没有自己的堆,它使用的堆是进程地址空间的一部分
1. 什么是Win32的堆?
一个Win32堆是一块保留地址空间。起初,该保留区域中的大部分页都没有用物理存储提交。当从堆中分配空间时,堆管理器会向堆提交更多的物理存储。当堆中空间被释放时,堆管理器会从堆中释放物理存储。物理存储是按页提交给堆的。
1.1 进程的缺省堆
当一个Win32进程被初始化时,系统在它的地址空间中创建了一个堆。该堆被称为进程的缺省堆。缺省时,该堆的区域是1MB。不贵,系统能增大进程的缺省堆。在编译程序时,可以使用/HEAP链接器开关来改变缺省的堆大小。DLL没有自己的堆,不应使用/HEAP开关。
- 进程的缺省堆被很多Win32函数使用。例如:new、malloc等默认都是从缺省堆上分配空间。
- 缺省堆的访问被序列化了,系统确保在任一时刻只可能有一个线程在缺省堆中分配或释放内存块。
1.2 创建自己的Win32堆
除了进程的缺省堆外,还能再进程的地址空间中创建更多的堆。一般来说,想要在应用程序中创建其他的堆主要有3个原因:
- 部件保护
- 更有效的内存管理
- 局部访问
1. 部件保护
在缺省堆中的内存混在一起,可能由于其中一个内存块访问异常导致其他内存块错误。可创建独立的堆,使问题局部化。
2. 更有效的内存管理
如果堆中包含的对象都是同样大小,在释放一个对象后,就能保证另一个对象能合适地得到这个空闲对象的空间。
3. 局部访问
在设计应用程序时,最好把要同时访问的对象放在一起。若对象的内存分布在多个内存页面中,可能会因为缺页,需要系统在RAM和页面文件之间交换页面,导致性能降低。而将同时访问的对象放在一起将降低这种可能性。
1.3 创建Win32堆
调用HeapCreate来创建额外的堆:
HANDLE
HeapCreate(
_In_ DWORD flOptions,
_In_ SIZE_T dwInitialSize,
_In_ SIZE_T dwMaximumSize
);
- flOptions