C18、堆栈

我们以前最常用的方法。用于分配较小的数据块:链表和树。无分配粒度和页面边界的问题。

缺点:速度慢,无法直接控制物理存储器的提交和回收。

一、进程的默认堆栈:

n         进程初始化时,系统在进程的地址空间创建。默认大小1MB。可以用/HEAP链接开关改变默认大小(DLL没有与其相关的堆栈!): /HEAP: reserve[,commit]

n         老的16位函数LocalAlloc,GlobalAlloc都是从默认堆栈中分配内存。

n         获取进程默认堆栈句柄:HANDLE GetProcessHeap();

二、为什么要创建辅助堆栈:

1.         保护组件

2.         更加有效的内存管理

3.         进行本地访问

4.         减少线程同步开销

5.         迅速释放

三、如何创建辅助堆栈:

HANDLE HeapCreate(

DWORD fdwOptions,//0HEAP _GENERATE_EXCEPTIONS~_NO_SERIALIZE

SIZE_T dwInitialSize, // 最初提交的字节数

SIZE_T dwMaximumSize); // 最大值,=0:可扩展到物理存储器用完为止。

n         HEAP_NO_SERIALIZE标志建议不用(但如果是单线程程序、或 只有单个线程访问该堆栈 使用互斥机制 则能安全使用)。如果不用该标志,调用堆栈函数的线程运行速度降低!

n         HEAP _GENERATE_EXCEPTIONS:如果内存分配出错时,会得到系统通知。

四、从堆栈中分配内存块:

PVOID HeapAlloc(

HANDLE hHeap, // 堆栈句柄

DWORD fdwFlags, // 影响分配的标志

SIZE_T dwBytes); // 字节数

fdwFlags

n         HEAP_ZERO_MEMORY:初始化为0

n         HEAP_GENERATE_EXCEPTIONS:如果内存不足,引发异常(STATUS_NO_MEMORY:内存不足, STATUS_ACCESS_VIOLATION:堆栈被破坏或参数错误);如果在HeapCreate使用了该标志,则不需要再设定;如果不设定该标志,HeapAlloc失败返回NULL

n         HEAP_NO_SERIALIZE:同上。

如果分配较大的内存块(1MB +-),最好用VirtualAlloc

五、改变内存块大小:

PVOID HeapReAlloc

HANDLE hHeap,

DWORD fdwFlags, // HEAP_REALLOC_IN_PLACE_ONLY:不移动位置,链表或树有必要用该标志,其他同上

PVOID pvMem, // 原地址

SIZE_T dwBytes); // 字节数

六、查询内存块大小:

SIZE_T HeapSize(

HANDLE hHeap,

DWORD fdwFlags, // =0 HEAP_NO_SERIALIZE

LPCVOID pvMem); // 地址

七、释放内存块(可能回收物理存储器):

BOOL HeapFree(

HANDLE hHeap,

DWORD fdwFlags, // =0 HEAP_NO_SERIALIZE

PVOID pvMem);

八、撤销堆栈(回收物理存储器):

BOOL HeapDestroyHANDLE hHeap);

九、C++堆栈操作函数:newdelete(在你的类中重载这两个操作符,在内部使用堆栈操作函数)

十、其他函数:

n         WIN98, 2000中均适用的函数:Heap32First, Heap32Next, Heap32ListFirst, Heap32ListNext.

n         仅仅用于WIN2000的函数:

1.         查询线程中堆栈句柄:

DWORD GetProcessHeaps(DWORD dwNumHeaps, PHANDLE pHeaps);

使用前,先分配一个HANDLE数组。

2.         测试堆栈的完整性:

BOOL HeapValidateHANDLE hHeap, //

DWROD fdwFlags,

LPCVOID pvMem;

如果hHeap = 0,在pvMem = NULL时,该函数遍历检查堆栈中的内存块;pvMem = 特定地址时,他只测试这个地址的内存块。

3.         合并地址中的空闲内存块并回收不包含已经分配的地址内存块的存储器页面:

UINT HeapCompact

HANDLE hHeap

DWORD fdwFlags); // =0 HEAP_NO_SERIALIZE

4.         线程同步的函数:

u       BOOL HeapLock(HANDLE hHeap);

u       BOOL HeapUnlock(HANDLE hHeap);

但,事实上,HeapAlloc, HeapSize, HeapFree等函数在内部调用这两个函数。自己很少调用这两个函数。

5.         BOOL HeapWalk(HANDLE hHeap, PPROCESS_HEAP_ENTRY pHeapEntry);用于调试,他使你能遍历堆栈的内容。使用前PROCESS_HEAP_ENTRY结构成员lpData=NULL初始化,返回TRUE可以查看结构成员。若要进入堆栈中下一内存块,再次调用该函数,pHeapEntry 为上次使用的地址。返回FLASE时,标识堆栈中已没有其它内存块了。(需要使用线程同步函数!)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值