我在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
我没有看到该进程的内存占用量有任何增加。那是为什么?
答案 0 :(得分:5)
您可能构建得非常优化。
在大多数现代系统中,gcc知道malloc返回一个非别名指针。也就是说,它永远不会返回相同的指针两次,它永远不会返回你在其他地方“保存”的指针。
我发现这很难想象,但有可能一次调用malloc并且反复使用它的返回值。原因是:
它知道你的记忆是一个死人的存储。即:你写信给它,但它从来没有被读过。已知指针没有别名,因此它没有转义为从其他地方读取,并且它没有标记为volatile。你的for循环本身/可能/被扔掉。
此时它可以一遍又一遍地使用相同的内存。
现在我觉得很难相信:gcc对malloc有多少了解? Malloc可能会产生任何副作用,比如增加一个全球'被称为'的次数'以'为我的房间涂上一层随机的蓝色'。看起来真的很奇怪,它会放弃呼叫,并认为它是无副作用的。地狱,'malloc'可以实现每100次调用返回NULL(可能不太符合规范,但可以说是谁)。
它不做的是代表你释放它。这超出了它所能“知道”的范围,进入了“做不被允许的事情”的领域。你被允许泄漏记忆,虽然它可能是蹩脚的。
这里有两件事情有用: 1)编译environmenet:os,编译器和命令行标志。
和2)反汇编最终的二进制文件。 (objdump或来自编译器)
答案 1 :(得分:2)
rss和%mem都是“当前进程使用的物理内存”。它有很多机会来填写内容。尝试添加vsz。我敢打赌,这会像你期望的那样增长。
答案 2 :(得分:-2)
当你意识到你没有使用它时,你的编译器正在通过释放分配的内存来帮助你(假设代码的优化版本甚至可以使用malloc)。你可能会尝试打印出指针的值(printf(“0x%x”,ptr);) - 我怀疑你会得到重复的值。更可靠的检查会将已知的位串写入内存,已经查看已分配的内存是否已包含该字符串。换句话说,在检查该位模式是否已经存在于已分配的空间中之后,不要再写i,而是一遍又一遍地写入0xdeadbeef0cabba6e。