13

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

我知道这是 2GB - 对吗?

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

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

4

5 回答 5

15

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

始终使用虚拟内存 - 所有内存都是虚拟的。

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

于 2011-04-16T12:36:37.167 回答
4

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

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

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

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

于 2011-04-16T12:36:22.207 回答
3

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

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

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

于 2011-04-16T12:36:36.050 回答
3

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

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

于 2011-04-16T12:54:59.183 回答
2

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

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

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

参见例如MSDN 上的Virtual Address Space或Wikipedia 上的 Virtual Address Space

于 2011-04-16T12:35:33.067 回答