32 位 Windows 上 C++ 应用程序可用的最大内存是多少?

Posted

技术标签:

【中文标题】32 位 Windows 上 C++ 应用程序可用的最大内存是多少?【英文标题】:What is the maximum memory available to a C++ application on 32-bit Windows? 【发布时间】:2011-08-06 21:15:49 【问题描述】:

只是想知道 C++ 应用程序使用的最大内存是否有限制

我知道这是 2GB - 对吗?

如果 C++ 应用程序尝试请求超过 2GB 的内存,这会导致内存崩溃吗?

最后一个问题 - 如果运行 C++ 应用程序的机器内存已经不足,并且 C++ 应用程序要求 100MB 的数组(即连续内存),操作系统是否会通过使用虚拟内存来解决这个问题?

【问题讨论】:

【参考方案1】:

它会导致动态内存分配失败,这通常会导致应用程序崩溃,但从技术上讲,可以编写应用程序来承受此事件。 2GB 确实是单个进程的用户地址空间大小——一个应用程序可以使用多个进程(最简单的例子:Chrome)。如果应用程序要求 100MB 的连续内存,则该内存必须实际上是连续的,即使在物理上不连续,如果没有足够的连续页面可用,则分配失败。

总是使用虚拟内存——所有内存都是虚拟的。

2GB 是大多数情况下的限制。通常情况下,2GB 用于用户,2GB 用于内核,但您可以要求 Windows 将 3GB 用于用户,1GB 用于内核(有一定风险),并且是 64 位,整个 4GB 的 32 位地址空间可供用户使用。仅当您将应用程序编译为 /LARGEADDRESSAWARE 时,增加的地址空间才可用。

【讨论】:

【参考方案2】:

限制取决于操作系统。标准 Linux 是 2 Gb,Solaris 是 3 Gb,Windows(我听说)是 2 或 3,具体取决于 PAE 的使用方式。

但是,您的数据无法获得全部 2G。您的代码将占用一些,您的程序堆栈将占用一些,C 库将占用一些,您引用的任何其他共享库也将占用一些。通常,操作系统会组织代码、堆和堆栈,以便它们之间存在有意的间隙。

至于你的最后一个问题:都是虚拟内存。您实际上要问的是“如果我机器中的程序使用所有物理内存,操作系统是否会使用交换。”答案是肯定的,但不是你想的那样。

CPU 只能访问物理 RAM。它对存储在磁盘上的数据一无所知。因此,为了给正在运行的进程提供物理内存,操作系统将从另一个进程中获取该内存。为了占用内存,它会将其写入交换。当其他进程需要访问内存时,操作系统会将其读回,可能会将其他进程的内存写入交换。

【讨论】:

【参考方案3】:

通常,32 位操作系统只能寻址 4GB 的物理 RAM。在实践中,这个限制往往会稍微低一些,但可以通过使用虚拟 RAM 来缓解。在某些版本的 Windows 上,可以通过使用 Physical Address Extension 来增加它。

对您的问题更重要的是,在 32 位 Windows 上,用户应用程序可用的地址空间也有 2GB 的限制。这对单个应用程序可以使用的内存量施加了严格的限制,而与可用的物理或虚拟 RAM 量无关。默认的 2GB 限制可以增加到 3GB。

以下页面详细解释了限制:http://msdn.microsoft.com/en-us/library/aa366778(v=vs.85).aspx

【讨论】:

实际上带有 PAE(物理地址扩展)的 32 位 x86 系统可以解决的问题不止于此。如果您更仔细地查看链接到的表,您会注意到 Windows Server 2008 的 32 位版本最多可以处理 64 GB。【参考方案4】:

虽然其他答案在通常情况下是正确的,但在 Windows XP 32 位中支持使用 Address Windowing Extensions 使用超过 3GB 的内存。

数据库服务器通常使用 AWE 来使它们能够访问非常大的内存集。它需要使用 Win API 来实际管理内存,所以显然只有在真正需要时才使用。

【讨论】:

哇,仿佛回到了 1985 年! @Anon:你怎么看出来的?因为有内存限制?这永远不会消失。 @Cody Gray - 1980 年代中期有几种方法可以超过 DOS 的 640k 限制。一种方法使用特殊板,将相对较小的内存库切换到保留空间。另一个仅在 80286 上工作,实际上会将其切换到保护模式,将一块内存复制到低地址空间,然后将其切换回实模式。 Google 搜索“DOS 扩展内存”【参考方案5】:

您可以访问的所有内存都是虚拟的 - 您不能直接从应用程序访问物理内存。操作系统将根据需要使用页面文件 - 您会看到许多应用程序耗尽物理内存所产生的影响是交换增加,并且速度明显减慢。

在 Win 32 位上,应用程序有 2GB 的虚拟地址空间可用。这用于映射可执行文件和 DLL,例如内存映射文件,用于堆栈和堆。这个空间通常有些碎片化。如果您的应用程序构建为“大地址感知”,并且操作系统是 64 位或配置为将用户/内核模式内存拆分为 3/1GB,那么 64 位的地址空间几乎为 4GB,32 位的地址空间为 3GB。位。

您可以分配的内存通常在 17-1800 MB 范围内。如果你分配小部分,你会达到这个目标,如果你尝试分配大的连续块,你可能会更早地达到限制,因为你的地址空间是碎片化的。

参见例如Virtual Address Space on MSDN 或 Virtual Address Space on Wikipedia

【讨论】:

在 64 位 Windows 上,标记为大地址感知的 32 位应用程序几乎是 4Gb,而不是 3Gb。

以上是关于32 位 Windows 上 C++ 应用程序可用的最大内存是多少?的主要内容,如果未能解决你的问题,请参考以下文章

64 位 windows server 2008 中的 32 位 informix 驱动程序不可用

检测32位或64位Windows

Windows x64 上 32 位和 64 位应用程序之间的进程间通信

在 64 位机器上注册 C++ DLL

检测 32 位或 64 位 Windows

如何使用 Visual C++ 2010 Express 从 32 位环境为 64 位 Windows 编译 Qt?