使用malloc分配更多的内存

这段代码片段每次从stdin中读取字母'u'时将分配2Gb,并在读取'a'时初始化所有分配的字符。

#include <iostream>
#include <stdlib.h>
#include <stdio.h>
#include <vector>
#define bytes 2147483648
using namespace std;
int main()
{
    char input [1];
    vector<char *> activate;
    while(input[0] != 'q')
    {
        gets (input);
        if(input[0] == 'u')
        {
            char *m = (char*)malloc(bytes);
            if(m == NULL) cout << "cant allocate mem" << endl;
            else cout << "ok" << endl;
            activate.push_back(m);
        }
        else if(input[0] == 'a')
        {
            for(int x = 0; x < activate.size(); x++)
            {
                char *m;
                m = activate[x];
                for(unsigned x = 0; x < bytes; x++)
                {
                    m[x] = 'a';
                }
            }
        }
    }
    return 0;
}

我在具有3Gb RAM的linux虚拟机上运行此代码。 在使用htop工具监视系统资源使用情况的同时,我意识到malloc操作不会反映在资源上。

例如,当我只输入'u'一次(即分配2GB堆内存)时,我看不到htop中的内存使用量增加2GB。 只有当我输入'a'(即初始化)时,我才看到内存使用量在增加。

因此,我能够比现有的“malloc”更多的堆内存。 例如,我可以使用malloc 6GB(这比我的内存和交换内存更多),并且malloc允许它(即malloc不返回NULL)。 但是当我尝试初始化分配的内存时,我可以看到内存和交换内存填满,直到进程终止。

- 我的问题:

1.这是一个内核错误?

2.有人向我解释为什么这种行为是被允许的?


它被称为内存过量使用。 您可以通过以root身份运行来禁用它:

 echo 2 > /proc/sys/vm/overcommit_memory

并且它不是我喜欢的内核功能(所以我总是禁用它)。 请参阅malloc(3)和mmap(2)和proc(5)

NB:经常echo 0而不是echo 2 - 但并不总是 - 也适用。 阅读文档(特别是我刚刚链接的proc手册页)。


man malloc (在线在线):

默认情况下,Linux遵循乐观的内存分配策略。 这意味着当malloc()返回非NULL时,不能保证内存真的可用。

所以当你只是想分配太多时,对你来说“谎言”,当你想使用分配的内存时,它会尝试为你找到足够的内存,如果它找不到足够的内存,它可能会崩溃。


不,这不是内核错误。 您已经发现了一种称为迟分页(或过分分配)的情况。

在你写一个字节给malloc (...)分配的地址之前,内核只是“保留”地址范围。 这当然取决于你的内存分配器和操作系统的实现,但是大多数好的内存分配器在内存首次使用之前不会产生大部分的内核开销。

囤积分配器是一个立即想到的大罪犯,通过广泛的测试,我发现它几乎从不利用支持晚期分页的内核。 如果您在分配之后立即对整个内存范围进行零填充,则可以始终减轻任何分配器中后期分页的影响。

像VxWorks这样的实时操作系统永远不会允许这种行为,因为延迟分页导致严重的延迟。 从技术上讲,它所做的只是将延迟关闭,直到后来的不确定时间。

有关更详细的讨论,您可能有兴趣了解IBM的AIX操作系统如何处理页面分配和过度使用。

链接地址: http://www.djcxy.com/p/86499.html

上一篇: Allocating more memory than there exists using malloc

下一篇: malloc() inside an infinte loop