只是想知道C ++应用程序使用的最大内存是否有限制
我知道这是2GB - 这是正确的吗?
如果C ++应用尝试请求超过2GB的内存会导致内存崩溃吗?
最后的问题 - 如果运行C ++应用程序的机器已经内存不足而且C ++应用程序要求100MB的阵列(即连续的内存),操作系统是否会通过虚拟内存来适应这种情况?
答案 0 :(得分:14)
它将导致动态内存分配失败,这通常会导致生成的应用程序崩溃,但从技术上讲,可以编写应用程序来承受此事件。 2GB确实是单个进程的用户地址空间大小 - 应用程序可能使用多个进程(最简单的示例:Chrome)。如果一个应用程序要求100MB的连续内存,那么即使没有物理上连续的内存也必须几乎是连续的,并且如果没有足够的连续页面,那么这是一个失败的分配。
始终使用虚拟内存 - 所有内存都是虚拟内存。
在大多数情况下, 2GB是限制。通常情况下,2GB用于用户,2GB用于内核,但可以要求Windows为用户提供3GB,为内核提供1GB(有一定风险),以及64位,整个4GB的32位地址空间可供用户使用。增加的地址空间仅在您将应用程序编译为/LARGEADDRESSAWARE
时才可用。
答案 1 :(得分:4)
限制取决于操作系统。标准Linux是2 Gb,Solaris是3 Gb,Windows是(我被告知)2或3,具体取决于PAE的使用方式。
但是,您没有为您的数据获得所有2G。你的代码会占用一些,你的程序的堆栈会占用一些,而C库会占用一些,你引用的任何其他共享库也会占用一些。通常,操作系统会组织代码,堆和堆栈,以便它们之间存在有意的间隙。
至于你的最后一个问题:它是所有虚拟内存。你实际要问的是“如果我机器中的程序使用所有物理内存,操作系统是否会使用交换。”答案是肯定的,但不是你想的那样。
CPU只能访问物理RAM。它对存储在磁盘上的数据一无所知。因此,为了给正在运行的进程提供物理内存,操作系统将从另一个进程中获取该内存。为了占用内存,它会将其写入交换。当其他进程需要访问内存时,操作系统会将其读回,可能会将其他进程的内存写入交换。
答案 2 :(得分:3)
虽然其他答案在通常情况下是正确的,但是使用Address Windowing Extensions在Windows XP 32位中支持使用超过3GB的内存。
数据库服务器通常使用AWE来使它们能够访问极大的内存集。它需要使用Win API来实际管理内存,因此显然只有在真正需要时才能使用。
答案 3 :(得分:2)
通常,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
答案 4 :(得分:1)
您可以访问的所有内存都是虚拟的 - 您无法直接从应用程序访问物理内存。操作系统将根据需要使用页面文件 - 通过让许多应用程序耗尽物理内存而看到的效果是交换增加,并且显着减慢。
在Win 32位上,应用程序有2GB的虚拟地址空间可用。这用于映射可执行文件和DLL,例如,内存映射文件,用于堆栈和堆。这个空间通常有点碎片。如果您的应用程序构建为“大地址识别”,并且操作系统是64位或配置为将用户/内核模式内存拆分为3 / 1GB,则64位的地址空间几乎为4GB,32-的地址空间为3GB位。
您可以分配的内存通常在17-1800 MB范围内。如果你分配小部分,你会达到这个目标,如果你试图分配大的连续数据块,你可能会提前很多,因为你的地址空间是碎片化的。
参见例如Virtual Address Space on MSDN或Virtual Address Space on Wikipedia
答案 5 :(得分:-1)
2GB限制仅适用于1个进程。您可以通过N个进程(32位)扩展应用程序以分配N x 2GB。操作系统必须仍为64位。而且你必须处理这些过程之间的沟通。