内部存款和储蓄器管理三

VirtualAlloc 分配的内部存款和储蓄器是以 4K 为最小单位、几次三番的内部存储器地址(但映射到真实的内部存款和储蓄器时它不肯定是延续的),
前边说了, 它不符合分配小内部存款和储蓄器(譬如唯有几个字节的变量); 局地的变量在 “栈”
中有先后自动管理,
那么那多少个全局的小变量怎么做吧? 那就要用到 “堆”.
9 q% /+ Q1 L, }1 F2 x$ D5 D! A

  • n! q4 O% a  Q5 x0 r3 Y那样看来,
    VirtualAlloc 分配的内存既不是 “栈” 也不是 “堆”; VirtualAlloc
    分配的内部存款和储蓄器地址是连接的, “堆” 中内容类同是不总是的, 所以管理 “堆”
    相比麻烦, 它是通过双线链表的构造情势管理的; 程序能够拥有多少个 “堆”,
    每贰个 “堆” 都会有三个句柄, 访问 “堆” 中的内容时先要找到这些 “堆”,
    然后再遍历链表, 那说不定就是 “堆” 比 “栈” 慢的有史以来原因.
    % T: Q5 B1 i+ [/ e9 r’ K#
    F——————————————————————————–2 p9 D6 w; y( h$ L0 m7 O, p
    0 g$ j% {! l+ M  K8 I/ c
    在 “堆” 中分配内部存款和储蓄器(HeapAlloc)前先要建立 “堆”(HeapCreate),
    就好像程序有默许的 “栈” 一样, 每一个顺序都有二个私下认可建立的 “堆”(能够用
    GetProcessHeap 获取那几个 “暗中同意堆” 的句柄), 我们在 Delphi 中用到 “堆” 时, 使用的正是以此
    “默许堆”. 如果让程序更灵敏地有着五个 “堆”, 要求求用到 API 函数.5 J0 g% Y9 L4 k0 Q

, T. P  l1 g& D( e建立 “堆”
时会同时交由真实内部存款和储蓄器的, 那在提请大内部存款和储蓄器时会极慢, 所以暗中认可堆也唯有 1M, 但
“暗中认可堆” 并不曾界定大小, 它会基于需求动态拉长.* L- e: ]8 k( e1 K# F

! I+ M; g* v4 S; /; o) X’ T有了
“暗中同意堆” 还有必不可少申请别的的 “堆” 吗? 那唯有在四线程中才能反映出来, 和
“栈” 区别, 程序会给各种线程分配3个 “栈区”; 而 “暗中认可堆”
是经过中的全数线程公用的, 当多少个线程使用 “暗中认可堆” 时, 另1个内需使用
“堆” 的线程就要先挂起等待, 也正是它们不能够而且使用; 只有经过 API
函数重新创建的私家堆才是互不干涉、最有功效的.5 C” O3 z( E4 r8 u” 凯雷德& t0 ?
——————————————————————————–; k0 W4 [‘ r# f1 w& r2 A1 b, A

  • o5 R& A! L. D4 d; d3 _先明白一下
    “堆” 相关的函数.) B’ j2 a* m( D% K% C) I;
    M7 g

  1. //建立堆; 注意建马上内定的尺码也是按页大小(PageSize)对齐的, 譬如钦赐15k, 实际会分配 16K.
  2. HeapCreate(
  3.   flOptions: DWO奥德赛D;     {堆属性选项, 见下表}
  4.   dwInitialSize: DWORubiconD; {起首尺寸, 单位是字节;
    该大小会被一贯付出到骨子里的内部存款和储蓄器}
  5.   dw马克西姆umSize: DWO兰德酷路泽D  {最大尺寸, 假设不限制最大值就设为 0}
  6. ): THandle;             {重回堆句柄; 退步重临 0, 但借使参数
    flOptions 允许了丰盛, 失利会重回万分标识}
    1. //flOptions 参数可选值:
  7. HEAP_NO_SE昂科雷IALIZE        = 1; {非互斥,
    此标记可允许三个线程同时做客此堆}
  8. HEAP_GENERATE_EXCEPTIONS = 4; {当建立堆出错开上下班时间,
    此标记可刺激一个更加并再次来到十分标识}
  9. HEAP_ZERO_MEMO逍客Y         = 8; {把分配的内部存款和储蓄器发轫化为 0}
    1. //flOptions 参数钦定有 HEAP_GENERATE_EXCEPTIONS 时,
      大概回到的不胜:
  10. STATUS_ACCESS_VIOLATION = DWO奇骏D($C0000005); {参数错误}
  11. STATUS_NO_MEMO中华VY        = DWOSportageD($C0000017); {内部存款和储蓄器不足}

复制代码


  1. //销毁堆
  2. HeapDestroy(
  3. hHeap: THandle {堆句柄}
  4. ): BOOL;       {}

复制代码


  1. //从堆中申请内存
  2. HeapAlloc(
  3.   hHeap: THandle; {堆句柄}
  4.   dwFlags: DWOLX570D; {内部存款和储蓄器属性选项, 见下表}
  5.   dwBytes: DWO酷路泽D  {申请内部存款和储蓄器的高低, 单位是字节}
  6. ): Pointer;       {重返内部存储器指针; 失利重临 0 或尤其,
    意况和创造堆是千篇一律}
    1. //dwFlags 参数可选值:
  7. HEAP_NO_SEENCOREIALIZE        = 1; {非互斥,
    此标记可允许七个线程同时做客此堆}
  8. HEAP_GENERATE_EXCEPTIONS = 4; {当建立堆出错开上下班时间,
    此标记可激发贰个充足并重临相当标识}
  9. HEAP_ZERO_MEMOGL450Y         = 8; {把分配的内部存款和储蓄器早先化为 0}
    1. {能收看那和堆的习性选项是同样的; 假如 dwFlags 参数设为 0,
      将使用堆的属性; 若是再度钦点将覆盖堆的质量}
  10. {别的: 即便堆是暗中同意堆, 也正是堆句柄来自 GetProcessHeap, dwFlags
    参数会被忽视}

复制代码


  1. //改变堆内部存储器的高低, 也正是重新分配
  2. HeapReAlloc(
  3.   hHeap: THandle; {句柄}
  4.   dwFlags: DWO途睿欧D; {内部存款和储蓄器属性选项; 该参数比 HeapAlloc 多出一个挑选,
    见下表}
  5.   lpMem: Pointer; {原内部存款和储蓄器指针}
  6.   dwBytes: DWOQX56D  {新的尺寸}
  7. ): Pointer;       {同 HeapAlloc}
    1. //dwFlags 参数可选值:
  8. HEAP_NO_SE大切诺基IALIZE          = 1;  {非互斥,
    此标记可允许三个线程同时做客此堆}
  9. HEAP_GENERATE_EXCEPTIONS   = 4;  {当建立堆出错开上下班时间,
    此标记可刺激3个万分并重临很是标识}
  10. HEAP_ZERO_MEMOOdysseyY           = 8;  {把分配的内部存款和储蓄器开头化为 0}
  11. HEAP_REALLOC_IN_PLACE_ONLY = 16;
    {此标志不允许改变原先的内存地方}

复制代码


  1. //获取堆中某块内部存储器的分寸
  2. HeapSize(
  3.   hHeap: THandle; {堆句柄}
  4.   dwFlags: DWO奇骏D; {内部存款和储蓄器属性; 可选值是 0 或 HEAP_NO_SE汉兰达IALIZE,
    后者可确定保证联合访问}
  5.   lpMem: Pointer  {内部存储器指针}
  6. ): DWOSportageD;         {成功再次来到字节为单位的轻重; 失败再次回到 $FFFFFFFF}

复制代码


  1. //释放堆中内定的内部存款和储蓄器块
  2. HeapFree(
  3.   hHeap: THandle; {堆句柄}
  4.   dwFlags: DWO途锐D; {内部存款和储蓄器属性; 可选值是 0 或 HEAP_NO_SERIALIZE}
  5.   lpMem: Pointer  {内部存款和储蓄器指针}
  6. ): BOOL;          {}

复制代码


  1. //验证堆
  2. HeapValidate(
  3.   hHeap: THandle; {}
  4.   dwFlags: DWORD; {}
  5.   lpMem: Pointer  {}
  6. ): BOOL;          {}

复制代码


  1. //整理堆
  2. HeapCompact(
  3.   hHeap: THandle; {}
  4.   dwFlags: DWORD  {}
  5. ): UINT;          {}

复制代码


  1. //锁定堆
  2. HeapLock(
  3.   hHeap: THandle {}
  4. ): BOOL;         {}

复制代码


  1. //锁定后的解锁
  2. HeapUnlock(
  3.   hHeap: THandle {}
  4. ): BOOL;         {}

复制代码


  1. //列举堆中的内部存款和储蓄器块
  2. HeapWalk(
  3.   hHeap: THandle;                {}
  4.   var lpEntry: TProcessHeapEntry {}
  5. ): BOOL;                         {}

相关文章