随笔 - 2146  文章 - 19 评论 - 11846 阅读 - 1267万

系统给程序的地址数是 4G, 为什么不是 3G 或 5G? 因为 32 位的指针的最大值就是 $FFFFFFFF, 它不能表示更多了, 究其根源这要回到 CPU 的寻址能力、地址总线等等.

在 Win64 下, 系统给程序的地址数达到了 16EB(0 - $FFFFFFFFFFFFFFFF), 也就是 18446744073709551616 个. 不过 Win64 还没有普及, 我们还得回到实际的 Win32.

就这 4G 的地址, 系统还要留下一半($80000000 - $FFFFFFFF, 这 2G 是各进程共享的)用作宏观管理; 只给程序 2G(0 - $7FFFFFFF).
就这 2G 的地址, 也不是全给用户的, 低端的 0 - $FFFF 是用于空指针分配, 禁止访问; 高端的 $7FFF0000 - $7FFFFFFF 也留出来作为进程的临界区, 也禁止访问. 其实进程的私有空间地址只有 $10000 - $7FEFFFF.

上面这个结果, 我们可以通过 GetSystemInfo 函数得到证实, 通过 GetSystemInfo 函数能获取一个 TSystemInfo 结构, 结构中的 lpMinimumApplicationAddress 和 lpMaximumApplicationAddress 分别表示程序(或动态链接库)可以访问的最低与最高的内存地址.
var
  si: TSystemInfo;
begin
  GetSystemInfo(si);
  ShowMessageFmt('%p-%p', [si.lpMinimumApplicationAddress, si.lpMaximumApplicationAddress]);
  {结果是: 00010000-7FFEFFFF}
end;

通过 GetSystemInfo 还能得到一个内存相关的重要参数: 页大小(PageSize)
var
  si: TSystemInfo;
begin
  GetSystemInfo(si);
  ShowMessage(IntToStr(si.dwPageSize)); {4096; 4096 字节也就是 4K}
end;

PageSize 是系统管理内存的基本单位, 之所以需要用 GetSystemInfo 获取不同系统的 PageSize 也会有区别.

我们需要知道的是, 用 VirtualAlloc 函数分配的内存就是以 PageSize(4K) 为最小单位的; 假如我们用 VirtualAlloc 给一个整数(4个字节)分配内存, 将会浪费 4092 个字节, 也就是说 VirtualAlloc 不适合分配小内存, 因而也有了多种分配内存的函数.

暂时放下这个话题, 先了解一下 "栈".

说到 "栈", 就想到 "堆", 还有 "堆栈" 指的也是 "栈"; "栈" 与 "堆" 都是程序可操作的内存区域($10000 - $FFEFFFF)中的某一小段.

系统函数中有 HeapReAlloc、GlobalAlloc 等分配 "堆" 的函数, 却没有分配 "栈" 的函数, 这是因为 "栈" 是程序自动管理的; 每个程序都从自己的可用地址范围内留出一块作为 "栈", 程序根据需要可以自动调节它的大小, 但咱们可以设置它的最大值与最小值. 在Delphi 中可以从这里设置:
Project -> Options -> Linker -> [Min stack size 和 Max stack size]

"栈" 用来暂存局部变量和函数参数, 由程序在需要时申请, 用完就释放.

因为 "栈" 的空间一般不是很大, 所以咱们一般不要把局部变量弄得太大(特别是在使用数组的时候);
因为访问 "栈" 比访问 "堆" 来的简洁, 速度快, 所以要尽量多用局部变量、少用全局变量.

posted on   万一  阅读(8676)  评论(12编辑  收藏  举报
编辑推荐:
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧


点击右上角即可分享
微信分享提示