C x86配置上的最大可用内存大小?

C x86配置上的最大可用内存大小?,c,windows,memory,x86,C,Windows,Memory,X86,我构建了一个基于x86配置的C语言的项目,如果我使用3GB的堆栈,就会导致故障或错误的结果 x86配置上的最大可用内存大小是多少 (开发环境有足够的内存;Windows 64位,16GB RAM。)您的问题不是Windows中可用的内存量。您只为堆栈请求了3Gb(不是内存,只是堆栈)。这很少见 例如,进程堆栈对FreeBSD(非windows)的正常限制如下: $ ulimit -a number of pseudoterminals (-P) unlimited sock

我构建了一个基于x86配置的C语言的项目,如果我使用3GB的堆栈,就会导致故障或错误的结果

x86配置上的最大可用内存大小是多少


(开发环境有足够的内存;Windows 64位,16GB RAM。)

您的问题不是Windows中可用的内存量。您只为堆栈请求了3Gb(不是内存,只是堆栈)。这很少见

例如,进程堆栈对FreeBSD(非windows)的正常限制如下:

$ ulimit -a
number of pseudoterminals            (-P) unlimited
socket buffer size       (bytes, -b) unlimited
core file size          (blocks, -c) unlimited
data seg size           (kbytes, -d) 33554432
file size               (blocks, -f) unlimited
max kqueues                     (-k) unlimited
max locked memory       (kbytes, -l) unlimited
max memory size         (kbytes, -m) unlimited
open files                      (-n) 230121
pipe size            (512 bytes, -p) 1
stack size              (kbytes, -s) 524288     <<<<<<<<<<<<<<<
cpu time               (seconds, -t) unlimited
max user processes              (-u) 12042
virtual memory          (kbytes, -v) unlimited
swap size               (kbytes, -w) unlimited

$ulimit-a
伪终端的数量(-P)不受限制
套接字缓冲区大小(字节,-b)不受限制
核心文件大小(块,-c)不受限制
数据段大小(千字节,-d)33554432
文件大小(块,-f)不受限制
最大队列数(-k)无限
最大锁定内存(KB,-l)不受限制
最大内存大小(千字节,-m)不受限制
打开文件(-n)230121
管道大小(512字节,-p)1

堆栈大小(kbytes,-s)524288在64位内核下,如果32位进程构建为“大地址感知”可执行文件,则它可以使用整个4GiB虚拟地址空间,减去开销。否则只有2GB

默认情况下,此选项未启用。开发人员在构建可执行文件时必须向链接器传递标志。该标志在MSVC上为
/largeaddressware
,在MinGW上为
--large address-aware

当一个大的地址感知程序在32位版本的Windows上运行,并且启用了/3GB开关时,它将能够映射最多3GB的虚拟地址空间(剩余的高1GB保留给内核)。但是,在64位Windows系统上,它应该能够映射所有4GB,从而减少一些开销

单个连续分配的大小将受到主可执行文件和DLL映射到内存中的位置(以及堆栈和任何其他随机分配)的限制,因为它当然必须在已在使用的任何页面之间进行


如果没有大地址感知功能,在Windows上运行的32位程序(无论是32位还是64位)默认情况下只有2 GB的虚拟地址空间,无论减去内核地址使用量和其他开销后Windows有多少虚拟地址空间可用

特别是,您的程序将永远不会接收超过2GB标记的用户模式虚拟地址映射,除非它通过声明自己为大地址感知来选择接收如此高的地址


过去,32位Windows使用内核和用户空间之间的2G:2G虚拟地址空间分割。一些程序可能依赖于两个指向不同对象的指针之间的差异,这两个指针适合于一个有符号正整数,或者ISO C不能保证的其他假设,LAA将破坏这些假设。非大地址感知确保了与此类程序的向后兼容性。()

根据:“x64 WOW64支持4 GB虚拟地址空间”。特别是,运行32位应用程序的64位Windows不应该为内核结构要求宝贵的虚拟地址空间,因为内核通过64位thunks以64位模式运行;Windows 64位,16GB内存——如果您的应用程序是32位的,那么额外的内存不会起任何作用。一个64位的应用程序可以使用所有的内存。@PaulMcKenzie:很确定OP的要点是有足够的物理内存来支持32位虚拟地址空间的完整4GiB,32位进程甚至可以使用,所以这不成问题。问题不是很清楚他们编译的是什么编译器或目标操作系统。据我所知,wow64上的所有ntdll系统调用都涉及到对32位ntdll的调用、到64位ntdll代码的长模式转换,然后是系统调用@纳诺法拉:谢谢,我还没意识到Windows使用了那种笨重的设计。Linux具有内核直接支持的32位ABI,因此32位用户空间可以直接使用
int0x80
syscenter
,而不必首先在用户空间中执行缓慢的远jmp。这很讽刺,因为32位代码在Windows上的应用比Linux广泛得多。(所以我希望32位代码能够以一种完全高效的方式进行WinAPI系统调用。)您的答案一开始显然是说所有程序都限制在2GB。但这只有在没有
/largeaddressware
的情况下才是正确的。有些程序就是这样构建的。“你说的话最终很清楚,但可能有更好的表达方式。”彼得考德斯修改了。我重新排列了你的段落顺序,并在顶部添加了一个新的摘要段落。我认为这样可以更快地了解关键点,然后填写细节。请随时回复或编辑进一步,这只是最简单的方式来显示我的想法提出的事实。谢谢,非常感谢。我一直忙于其他突然出现的事情,所以我没有时间进行如此详细的编辑。是的,我已经将/LargeAddressware放入超过2GB的内存区域。从你的详细解释中,我终于明白了我的系统有多大的局限性。祝你有一个愉快的一天:)谢谢你的回答,我也知道3GB的堆栈是不常见的,但在这种情况下,我应该使用大约3GiB的堆栈,然后我发现了什么是一个限制。你使用这么多的堆栈空间是什么?我从来没有达到过这个数目。我使用了超过17Gb的虚拟内存,但从来没有使用过这么多的堆栈。@Luis Colorado在我的应用程序中,我调用了pthread库,每个线程句柄需要多达500MB的独立内存空间来存储变量。但正如您所知,x86配置对映像大小的限制在0x8000000以下,因此我将每个线程的属性内存空间用于创建内部变量,而不是创建全局变量(如果我使用全局变量并创建6个线程,映像大小将变小)