如果我尝试分配内存:
int ramSize = magicLibrary.getRamSize();
assert(ramSize*2 <= pow(2,64-8));//Don't overflow the 64 bit limit (32 on some systems).
int * mainData new int[ramSize*2/sizeof(int)]; //2 times too big.
我会得到磁盘交换来填充空间吗?如果没有,我该如何使用交换?
只要 RAM 和 Swap-space 都没有完全耗尽,并且地址空间有限制(即 32 位 2-3GB,超过 64 位系统中的 ram),系统就会允许您分配内存。如果 RAM 用尽,系统将使用交换空间。
有时,操作系统也会允许“overcommit”,这与航空公司“期望一些乘客不会出现”时的做法基本相同,因此他们会为该航班多卖几张机票,并担心“所有座位都满了”当他们到了那个地步。就计算机而言,这意味着操作系统很可能允许您分配比实际可用内存更多的内存,并且稍后通过某种方式解决“没有足够”的错误(通常通过释放一些内存) “备用”或“杀死一些随机应用程序”)。操作系统允许这样做的原因是应用程序经常分配未完全使用的大块内存。用零填充的内存区域也可以“合并”为“写时复制”内存,这样,如果您稍后对其进行写入,它会生成该内存的新副本。这也可能意味着,如果您分配大量内存,则必须实际向其写入一些内容(除了零?)以使其“处于使用状态”。同样,这反映了应用程序的典型行为“分配大量内存,用零填充,然后只使用其中的一部分”——因此操作系统试图通过没有大量的“页面”来“节省空间”它们中的零”。
请注意,内存是在 RAM 中还是 Swap 是一个动态标准 - 内存一直在换入和换出,程序代码和数据都可以随时换出,然后在需要时再带回来。不管这是“堆”还是其他内存,所有内存在这方面都差不多。
目前还不完全清楚您真正想要实现的目标,但希望这至少可以解释发生了什么。
哦,假设ramSize
是字节数,这几乎肯定总是错误的:
assert(ramSize*2) <= 2^(64-8)
因为ramSize * 2 > 0
和(2 XOR 56) = 0
。
首先,new
对swap一无所知。这是操作系统的工作(至少对于通用操作系统,比如您正在使用的操作系统),它将决定何时交换以及交换什么。
话虽如此,您分配那么多内存的尝试几乎肯定会失败。即使有足够的交换内存可用,操作系统也会为自己保留大量的虚拟地址空间,这意味着您可以分配的空间是有限的。例如,在 32 位 Windows 上,为内核保留了 2GB 的地址,如果您尝试过,您将无法分配 4GB 的虚拟内存,因为没有足够的可用地址来表示那么多内存。
你到底想做什么?
简而言之,交换空间是硬盘上的虚拟内存部分,在 RAM 已满时使用。这是操作系统的工作,而不是新的操作员!
如果使用new
,操作系统会收到内存请求。然后它决定从哪里获得该内存。
与打开文件或使用 cout 回显相同。这些东西是c++内置的。
所以你的程序可能已经使用了交换,但你不知道它。
如果您想了解有关此主题的更多信息,您可能需要查看 unix 的内部工作原理(当前使用的每个操作系统的母亲和父亲)。