《Windows核心编程》读书笔记(14) 第18章 堆栈

第18章堆栈

对内存进行操作的第三个机制是使用堆栈。

堆栈的优点是,可以不考虑分配粒度和页面边界之类的问题,集中精力处理手头的任务。堆栈的缺点是,分配和释放内存块的速度比其他机制要慢,并且无法直接控制物理存储器的提交和回收。


从内部来讲,堆栈是保留的地址空间的一个区域。开始时,保留区域中的大多数页面没有被提交物理存储器。当从堆栈中进行越来越多的内存分配时,堆栈管理器将把更多的物理存储器提交给堆栈。物理存储器总是从系统的页文件中分配的,当释放堆栈中的内存块时,堆栈管理器将收回这些物理存储器。

进程的默认堆栈

当进程初始化时,系统在进程的地址空间中创建一个堆栈。该堆栈称为进程的默认堆栈。按照默认设置,该堆栈的地址空间区域的大小是1MB

当创建应用程序时,可以使用/HEAP链接开关,改变堆栈的1MB默认区域大小。由于DLL没有与其相关的堆栈,所以当链接DLL时,不应该使用/HEAP链接开关。

由于进程的默认堆栈可供许多Windows函数使用,你的应用程序有许多线程同时调用各种Windows函数,因此对默认堆栈的访问是顺序进行的。

系统必须保证在规定的时间内,每次只有一个线程能够分配和释放默认堆栈中的内存块。如果两个线程试图同时分配默认堆栈中的内存块,那么只有一个线程能够分配内存块,另一个线程必须等待第一个线程的内存块分配之后,才能分配它的内存块。一旦第一个线程的内存块分配完,堆栈函数将允许第二个线程分配内存块。这种顺序访问方法对速度有一定的影响。

单个进程可以同时拥有若干个堆栈。这些堆栈可以在进程的寿命期中创建和撤消。但是,默认堆栈是在进程开始执行之前创建的,并且在进程终止运行时自动被撤消。不能撤消进程的默认堆栈。每个堆栈均用它自己的堆栈句柄来标识,用于分配和释放堆栈中的内存块的所有堆栈函数都需要这个堆栈句柄作为其参数。

HANDLE GetProcessHeap();

为什么要创建辅助堆栈

保护组件。

更加有效地进行内存管理。
进行本地访问。
减少线程同步的开销。
迅速释放。

如何创建辅助堆栈

可以在进程中创建辅助堆栈,方法是让线程调用HeapCreate函数:

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

如果堆栈创建成功,HeapCreate函数返回一个句柄以标识新堆栈。该句柄可以被其他堆栈函数使用。


从堆栈中分配内存块

若要从堆栈中分配内存块,只需要调用HeapAlloc函数:



改变内存块的大小

有些应用程序开始时分配的内存块比较大,然后,当所有数据放入内存块后,再缩小内存块的大小。有些应用程序开始时分配的内存块比较小,后来需要将更多的数据拷贝到内存块中去时,再设法扩大它的大小。如果要改变内存块的大小,可以调用HeapReAlloc函数:


了解内存块的大小

当内存块分配后,可以调用HeapSize函数来检索内存块的实际大小:


释放内存块

当不再需要内存块时,可以调用HeapFree函数将它释放:


撤消堆栈

如果应用程序不再需要它创建的堆栈,可以通过调用HeapDestroy函数将它撤消:


C++程序来使用堆栈

使用堆栈的最好方法之一是将堆栈纳入现有的 C++ 程序。在 C++ 中,调用 new 操作符,而不是调用通常的 C 运行期例程 malloc ,就可以执行类对象的分配操作。然后,当我们不再需要这个类对象时,调用 delete 操作符,而不是调用通常的 C 运行期例程 free 将它释放。




  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值