6

我在一个scratchbox交叉编译环境中并且有这个

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

int main()
{
    int * ptr;
    int i=0;

    while(1)
    {
        ptr = (int*)malloc( 10485760 * sizeof(int) );

        if(ptr == NULL)
        {
            printf("Could not malloc\n");
            exit(1);
        }

        else
        {
            printf("Malloc done\n");
            for (i = 0 ; i <= 10485759 ; i++)
            {
                ptr[i] = i ;
            }
            sleep (5);
            continue;
        }
    }
}

当我运行二进制文件并执行

ps -p pid -o cmd,rss,%mem

我没有看到进程的内存占用有任何增加。这是为什么?

4

3 回答 3

5

您可能构建得非常优化。

在大多数现代系统上 gcc 知道 malloc 返回一个非别名指针。也就是说,它永远不会返回相同的指针两次,也永远不会返回您在其他地方“实时”保存的指针。

我发现这很难想象,但有可能 malloc 被调用一次并且它的返回值被一遍又一遍地使用。原因是:

它知道你的记忆是一个死店。即:你写它,但它永远不会被读取。已知指针没有别名,因此它没有转义以从其他地方读取,也没有标记为易失性。您的 for 循环本身 / 可能 / 被丢弃。

那时它可以一遍又一遍地使用相同的内存。

现在这就是为什么我很难相信:gcc 对 malloc 了解多少?Malloc 可能会产生任何副作用,例如增加全局“调用次数”以“将我的房间随机涂成蓝色”。它会挂断电话并假设它没有副作用,这似乎真的很奇怪。见鬼,'malloc' 可以实现为每 100 次调用返回 NULL(可能不完全符合规范,但谁能说)。

它没有做的是代表您释放它。这超出了它“可能”知道的范围,并进入了“做它不允许做的事情”的领域。你被允许泄漏内存,虽然它可能是蹩脚的。

有两件事在这里有用:1) 编译环境:哪些操作系统、编译器和命令行标志。

2) 最终二进制文件的反汇编。(objdump 或来自编译器)

于 2012-05-25T00:15:19.333 回答
2

rss 和 %mem 都是“当前进程正在使用的物理内存”。它有很多机会将内容分页。尝试添加 vsz。我敢打赌,它会按您的预期增长。

于 2012-05-25T00:14:03.820 回答
-2

Your compiler is helping you out by freeing the allocated memory (assuming that the optimized version of your code even gets around to doing the malloc) when it realizes that you aren't using it. You might try printing out the value of the pointer (printf("0x%x", ptr);) - I suspect you'll be getting repeating values. A more reliable check would write a known bitstring into memory, having already looked to see if the allocated memory already contains that string. In other words, instead of writing i, write 0xdeadbeef0cabba6e over and over again, after checking to see if that bit pattern is already in the space you have allocated.

于 2012-05-25T00:06:07.217 回答