我已经创建了Virtual Ram类来在运行时提升内存分配。
class VRam
{
unsigned char ***data;
...
public:
VRam(ulli length);
void *allocate(ulli size);
...
}
在我的程序中,小数组或变量在组内存中分配,这允许我在开始时分配一个巨大的数组,稍后再使用它的某些部分然后清除整个事物。 问题如下: 我最近更新了它,通过将它们分成更小的块来支持大型数组。我的程序在此更新后工作得很好,但即使我将内存限制设置为2 GiB(此开始时分配的空间量),系统监视器显示它仅使用50 MiB,这很奇怪。经过一些测试:
ulli size = 2073741824;
int blocknum = size / VBLOCK_SIZE;
VRam *vr = new VRam(size);
int **arrs = new int*[blocknum];
for (int i = 0; i < blocknum; ++i) {
//cout<<i<<endl;
arrs[i] = (int*)vr->allocate(VBLOCK_SIZE);
arrs[i][0] = i; //<<<<<---------------
for (int j = 0; j < VBLOCK_SIZE / 4; ++j) {
//cout<<" "<<j<<endl;
arrs[i][j] = j+i; //<<<<-------------
}
}
我得到了以下结果: 如果我在分配的内存上构造所有内容,它将真正被分配,(第二个&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt;&lt; ----)并且它使用指定的空间量如果我不使用不构造所有东西(没有或前几个字节:第一个&lt;&lt;&lt; ---),那么将不使用内存。我可以在我的笔记本电脑上使用8 GiG Ram指定16个GiB,它仍在工作。 我的问题是,因为它似乎是某种内存优化,但我创建这个类的原因是使用内存来提升CPU。 这会导致速度有任何问题吗?如果是这样的话,如何在不写入内存中的每个字节的情况下绕过它? 我正在使用qmake编译Ubuntu 16.04 LTS(Qt 5.5.1 GCC 5.2.1 20151129,64位)。
答案 0 :(得分:1)
这是因为Linux内存分配器的性质:它使您的进程认为它可以访问所需的内存量。但是,当您的进程实际触及它时(即通过读/写),内存是真正分配的。
引用malloc(3):
默认情况下,Linux遵循乐观的内存分配策略。这意味着当malloc()返回非NULL时,无法保证内存确实可用。
答案 1 :(得分:1)
您可能对this document感兴趣,其中详细介绍了Linux如何处理内存过量使用。
TL; DR是Linux将允许进程分配大量内存,但实际上只有在写入时才使用它。
答案 2 :(得分:1)
您需要了解虚拟内存和物理内存之间的区别。物理内存是机器中的实际RAM,它相当快(但比缓存或寄存器访问慢得多)。您要分配的是虚拟内存:在过去的30年或40年中,几乎每个严肃的操作系统都能够分配比物理内存更多的虚拟内存。
当你触摸一些虚拟内存时,它将被带入物理内存(通过从交换文件中复制它,或者,如果这是第一次通过将相应的物理内存归零来触摸虚拟内存)。当您的物理内存不足时,虚拟内存将被复制到交换文件中。
如果需要将虚拟内存复制到交换文件或从交换文件复制虚拟内存,这将非常慢。你想避免这么做太多。