我通常会在我的浏览器(Pale Moon x86)中运行几百个标签,这经常会使程序的内存使用量高达 2-3GB。
当程序运行到内存限制时会发生什么?系统是否只是继续向其提供内存,但“现在”是以磁盘交换的形式?程序是否“知道”它已经达到系统的内存限制?
直到最近,我才突然意识到,为什么浏览器的内存大小不再继续增长,并且开始出现可怕的性能下降——32/64 位内存空间!
所以我现在开始转向 Waterfox,一个 x64 版本。x64 程序的内存使用量是否会持续增长,直到系统说“不再增长”?
答案1
当 32 位程序(在 64 位机器上运行)达到内存限制时会发生什么?
在 32 位系统上也会发生同样的事情:程序在某种程度上失败了。
对于 32 位程序而言,“宇宙”包括取决于4GB 的数据。它不知道自己小盒子外面的更大区域(想想 Michio Kaku 在他的书中使用的鱼的比喻超空间)。
如果你打开太多标签页,导致内存占用率上升,它就会占满整个空间,当内存用完时,它会抱怨没有足够的内存来打开新标签页或显示图片等。如果写得好,它会抱怨;如果写得不好,它就会崩溃。
从底层编程的角度来思考。32 位程序使用 32 位指针来存储数据。这意味着它最多可以指向 4GB 的数据。如果它已经用完了 4GB,那么即使操作系统可以给它更多,新指针的值又是多少呢?新地址太远了,程序无法将这么大的地址放在 32 位指针中。
打个比方,想想电话号码。假设您所在的城市人口不多,所以您的电话号码都是 5 位数,最多可容纳 10,000 个号码,因此您的所有通讯录最多可容纳 10,000 个电话号码。但是,这个国家人口众多,所以它使用 7 位数的数字。即使这个国家能给你一个远方人的电话号码,你将无法将其存储在你的地址簿中,因为你只有 5 位数字的空间来打印数字,所以一旦你打印了 10,000 个数字,这本书就完全满了。
答案2
32 位应用程序只有 32 位地址空间,即使在 64 位系统上也是如此,因此它无法使用超过 4 GB 的虚拟内存(可能远少于 4 GB)。64 位应用程序具有更大的地址空间,因此可以使用更多虚拟内存。但是 RAM 是有限的,当 RAM 已满时,数据将进入页面文件,这会降低整个系统的速度(通常会大幅降低)。
答案3
当 32 位程序开始接近虚拟内存(地址空间)限制时,其内存分配将开始失败。进程所做的每次内存分配都需要进程虚拟内存空间中有足够的可用、连续的地址空间,对于 32 位进程,这个数字是 4GB。在 Windows 7 上,如果 64 位操作系统上的 32 位程序支持大地址,则 2GB 和 3GB 限制不适用于它们。(每个重要的现代程序都应该支持大地址。)
当内存分配失败时,进程会做什么由它自己决定。通常,程序会尝试通过丢弃不需要的任何东西、取消映射未使用的文件等方式来压缩内存使用量。但最终,它只能拒绝执行任何操作。
有些程序确实实现了分页形式,即它们将结构写入文件以便稍后读取。它们将一直保留在 RAM 中,但由于需要处理映射,因此速度仍然会较慢。