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

时间:2014-08-06 16:00:02

标签: c++ memory memory-leaks

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

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

因为实际上我在64位系统中运行了一个32位程序,但当程序只分配了大约1.5GB的内存时程序因内存泄漏而崩溃......我似乎无法想象为什么。

(Oooops ...对不起家伙我认为我在第一个问题上犯了一个简单的错误......实际上,一个十六进制数字是4位,8位是32位。但是这里有另一个问题......地址是如何表示的一个64位的程序?)

3 个答案:

答案 0 :(得分:9)

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

如果您的程序可识别大地址空间,则此限制在32位系统上增加到3GB,在64位Windows上运行的32位程序增加到4GB。

对于大地址空间感知程序(IMAGE_FILE_LARGE_ADDRESS_AWARE)的更高限制,请参见此处:

您可能还想查看Virtual Memory article on Wikipedia以更好地了解虚拟地址和物理地址之间的映射是如何工作的。上面的第一个MSDN链接也有一个简短的解释:

  

进程的虚拟地址空间是一组虚拟内存   它可以使用的地址。每个进程的地址空间是   私有,除非共享,否则不能被其他进程访问。   虚拟地址不代表实际的物理位置   记忆中的一个对象;相反,系统维护一个页表   每个进程,这是一个用于翻译的内部数据结构   虚拟地址到其对应的物理地址。每   当线程引用地址时,系统会转换虚拟   地址到物理地址。 32位的虚拟地址空间   Windows的大小为4千兆字节(GB),分为两个分区:   一个供该过程使用,另一个供该过程使用   系统。有关64位虚拟地址空间的更多信息   Windows,请参阅Virtual Address Space in 64-bit Windows.


编辑:作为user3344003 points out,这些值您可以使用malloc分配的内存量或以其他方式用于存储值,它们只代表虚拟地址空间的大小。

答案 1 :(得分:2)

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

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

我可能省略了其他一些限制。

- = - = - = - = -

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

- = - = - = - = - =

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

答案 2 :(得分:0)

参考以下article

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

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

你怎么能找到崩溃时分配的内存呢?