这似乎是一个非常普遍的问题,但我还没有找到明确的答案。
我可以访问运行linux的服务器,具有16 GB的RAM和16核(64位)的CPU (/ proc / cpuinfo给出“Intel(R)Xeon(R)CPU E5520 @ 2.27GHz”)。但是,内核 是32位(uname -m给出i686)。当然,我没有root权限,所以我无法改变 这一点。
我正在运行一个C ++ - 我写的程序,它做了一些需要内存的计算,所以我 我需要一个大堆 - 但每当我尝试分配超过2GB时,我得到一个badalloc, 虽然ulimit返回“无限”。 为简单起见,我们只说我的程序是这样的:
#include <iostream>
#include <vector>
int main() {
int i = 0;
std::vector<std::vector<int> > vv;
for (;;) {
++i;
vv.resize(vv.size() + 1);
std::vector<int>* v = &(vv.at(vv.size() - 1));
v->resize(1024 * 1024 * 128);
std::cout << i * 512 << " MB.\n";
}
return 0;
}
使用g ++(无标志)编译后,输出为:
512 MB.
1024 MB.
1536 MB.
2048 MB.
terminate called after throwing an instance of 'std::bad_alloc'
what(): std::bad_alloc
Aborted
据我了解,这是32位系统的限制,显然是因为32位指针 可以只容纳2 ^ 32个不同的地址(如果我编译了相同的程序,我是否正确 在同一台服务器上,但该服务器运行的是64位内核,而不是程序可以分配的内核 2GB?)
这不是分配的内存是否是连续的问题,如果我切片更薄 示例程序,同样的问题发生了,在我的实际程序中,没有大块的 记忆,只是很多小记忆。
所以我的问题是: 有什么我能做的吗?我无法更改操作系统,但当然我可以修改我的源代码, 使用不同的编译选项等...... 但我确实需要超过2GB的内存,而且没有明显的方法可以进一步优化 程序使用的算法。
如果答案是明确的“否”,那么知道这一点仍然是好事。
谢谢, 卢卡斯
答案 0 :(得分:5)
如果您需要内存一次,不,没有更改为64位内核就没有办法做到这一点(是的,允许您分配更多内存)一个过程)
也就是说,如果您不需要同时使用内存,而只需快速访问,则可以随时将部分内存存储卸载到另一个进程。
例如,可以将数据存储在另一个进程中,并让您的进程在需要时临时将共享内存从该进程映射到自己的内存空间。它仍将存储在内存中,但在切换内存范围时会有一些开销。如果开销是否可接受将取决于您的内存访问模式。
这不是一个非常简单的方法,但是如果不改变内核来为你提供64位的地址空间,那么听起来你有点像绑定。
编辑:你可以通过重新配置内核将限制提高到略高于2GB,但这只意味着你会在那里达到硬限制。此外,这将需要root访问权限。答案 1 :(得分:0)
答案很清楚“不”。如果无法更改操作系统,则无法提高限制。该限制适用于整个过程,显然没有单个分配可以超过每个过程的限制。
根据用于编译内核的选项,限制可能高于2GB,但肯定会小于4GB。但我想重新编译内核也算是“改变操作系统”。
是的,在64位操作系统上,限制会消失。