32位c++程序的最大可寻址内存空间是多少?

What is the max addressable memory space in a 32-bit C++ program?

本文关键字:空间 内存 多少 寻址 程序 c++ 32位      更新时间:2023-10-16

在调试模式下,我看到指针的地址像0x01210040,但我意识到,0x是十六进制,对吧?有8个十六进制数字,即总共有128位被寻址??那么,这是否意味着对于32位系统,前两位总是0,而对于64位系统,第一位总是0?

另外,我可以问一下,对于32位程序,只要我留在堆中并且只使用malloc(),我就可以分配多达3GB的内存吗?或者是Windows系统对单线程设置了一些限制?(我使用的IDE是VS2012)

因为实际上我在64位系统中运行一个32位程序,但是当它只分配了大约1.5GB的内存时,程序崩溃了内存泄漏…我似乎不明白为什么。

(糟糕…对不起,我想我在第一个问题上犯了一个简单的错误…事实上,一个十六进制数字是4位,8位是32位。然而,这里有另一个问题……地址在64位程序中如何表示?)

对于32位Windows,每个进程的可用限制实际上是2GB,从0x00000000(或简称0x0)到0x7FFFFFFF的虚拟地址。其余的4GB地址空间(0x800000000xFFFFFFFF)供Windows本身使用。请注意,这些与实际的物理内存地址无关。

如果你的程序对大的地址空间敏感,这个限制在32位系统上增加到3GB,在64位Windows上运行的32位程序增加到4GB。

  • http://msdn.microsoft.com/en-us/library/windows/desktop/aa366912 (v = vs.85) . aspx

对于大型地址空间感知程序(IMAGE_FILE_LARGE_ADDRESS_AWARE)的更高限制,参见这里:

  • http://msdn.microsoft.com/en-us/library/aa366778.aspx

你可能还想看看维基百科上的虚拟内存文章,以更好地理解虚拟地址和物理地址之间的映射是如何工作的。上面的第一个MSDN链接也有一个简短的解释:

进程的虚拟地址空间是一组虚拟内存它可以使用的地址。每个进程的地址空间为私有的,除非被共享,否则不能被其他进程访问。虚拟地址并不代表设备的实际物理位置内存中的对象;相反,系统维护一个页表每个进程,这是一个内部的数据结构,用于翻译将虚拟地址转换成相应的物理地址。每一个当线程引用一个地址时,系统将转换该虚拟地址地址到物理地址。32位的虚拟地址空间Windows的大小为4gb,分为两个分区:一个供进程使用,另一个保留给进程使用系统。有关64位虚拟地址空间的更多信息Windows,参见64位Windows中的虚拟地址空间。


EDIT:正如user3344003指出的,这些值不是您可以使用malloc或其他方式用于存储值分配的内存量,它们只是表示虚拟地址空间的大小。

有许多限制可以限制malloc分配的大小。

1)位的数目,限制了地址空间的大小。对于32位,就是4B。2)系统细分为各种处理器模式。现在,通常2GB归用户,2GB归内核。地址空间可能受到页表大小的限制。4)总虚拟内存可能受到页面文件大小的限制。在你开始malloc之前,在虚拟地址空间中已经有了一些东西(例如,代码堆栈,保留区域,数据)。malloc需要返回一个连续的内存块。它可以返回的最大理论块必须适合未分配的虚拟内存区域。6)您的内存管理堆可能会限制可分配的大小。

可能还有我省略的其他限制。

-=-=-=-=-

如果您的程序在通过malloc分配1.5GB后崩溃,您是否检查从malloc返回的值以查看它是否为空?

-=-=-=-=-=

分配大块内存的最佳方法是通过操作系统服务将页面映射到虚拟地址空间。——不使用malloc

参考以下文章

对于在32位Windows上启动的32位应用程序,所有上述数据类型的总大小不得超过2gb。在64位系统中启动的同一个32位程序可以分配大约4gb(实际上大约3.5 gb)

由于windows占用的空间,您正在查看的实际数据约为1.7 GB。

当它崩溃时,你是如何发现它分配的内存的?