对于使用(...仍然必须使用)32 位二进制文件的系统来说,这是一个有用的功能,并且考虑了 4G 限制。
它本质上意味着,32 位用户空间代码、32 位用户空间数据和(带有 PAE 的 32 位,或 64 位)内核位于不同的地址空间,本质上使进程能够使用几乎所有可能的最大 4G 地址空间来存储其数据。
除了一些古代公告,不幸的是我再也找不到了:
我很高兴地宣布首次公开发布针对 2.5.74 Linux 内核的“4GB/4GB VM split”补丁:
http://redhat.com/~mingo/4g-patches/4g-2.5.74-F8
4G/4G 分割功能主要适用于大 RAM x86 系统,这些系统希望(或必须)获得更多内核/用户 VM,但代价是每个系统调用的 TLB 刷新开销。
众所周知,在 x86 上,虚拟内存总量限制为 4GB。在这总共 4GB 的 VM 中,用户空间使用 3GB (0x00000000-0xbffffffff),内核使用 1GB (0xc0000000-0xffffffff)。这种 VM 方案称为 3/1 分割。这种分割在 RAM 达到 1 GB 之前都可以正常工作 - 即使在 1 GB RAM 之前,它也能正常工作,因为“highmem”将各种较大的缓存(和对象)移动到高内存区域。
在我的测试中,我的一些进程在大约 2-3 GB 时开始崩溃。
我怎样才能做到这一点?我使用相对较新的内核(4.10)。我可以在 32 位用户空间上使用 64 位内核,或者使用 32 位 PAE 内核。
如果只有部分进程使用 4G/4G 就足够了,但它们似乎确实需要它。
答案1
在 64 位内核上,您已经拥有可供 32 位用户空间程序访问的完整 4G 空间。通过在终端中输入以下内容来查看自己(警告:如果运行此命令时您的系统没有可用的 4GiB RAM,则系统可能会变得无响应):
cd /tmp
cat > test.c <<"EOF"
#include <stdlib.h>
#include <stdio.h>
int main()
{
size_t allocated=0;
while(1)
{
const size_t chunkSize=4096;
char* p=malloc(chunkSize);
if(!p) return 0;
*p=1;
allocated+=chunkSize;
printf("%zu\n",allocated);
}
return 0;
}
EOF
gcc test.c -o test -m32 && ./test | tail -n1
在我的 x86_64 内核 3.12.18 上,我得到的4282097664
结果约为 4GiB-12.3MiB,因此考虑实现 4G/xG 分割是公平的。