C和内存使用中的malloc()

时间:2012-02-17 15:54:54

标签: c memory memory-leaks memory-management malloc

我正在尝试使用malloc来查看是否可以分配所有可用内存。

我使用了以下简单程序并提出了一些问题:

int main(void)
{
    char * ptr;
    int x = 100;

    while(1)
    {
        ptr = (char *) malloc(x++ * sizeof(char) / 2);
        printf("%p\n",ptr);
    }

    return 0;
}

1)为什么当使用更大的数据类型(int,unsigned long long int,long double)时,进程会使用更少的内存,但是使用更小的数据类型(int,char)会使用更多?

2)运行程序时,它会在达到一定数量后停止分配内存(在Windows 7 64位上为~592mb,8GB RAM交换文件设置为系统管理)。打印输出如果显示0表示NULL。为什么在达到此阈值后停止分配内存而不耗尽系统内存并交换?

我发现以下帖子中的某个人尝试了和我一样的东西,但他们没有看到内存使用情况有任何差异,但我是。 Memory Leak Using malloc fails

我在Linux内核2.6.32-5-686上尝试了类似结果的代码。

任何帮助和解释都将不胜感激。

谢谢,

4 个答案:

答案 0 :(得分:4)

1)通常内存以页面的倍数分配,因此如果您要求的大小小于一个页面,malloc将至少分配一页。

2)这是有道理的,因为在多任务系统中,您不是唯一的用户,并且您的进程不是唯一运行的进程,还有许多其他进程共享一组有限的资源,包括内存。如果操作系统允许一个进程分配所需的所有内存而没有任何限制,那么它实际上并不是一个好的操作系统,对吧?

最后,在Linux中,内核在你真正开始使用这个内存之前不会分配任何物理内存页面,所以只是调用malloc实际上不会消耗任何物理内存,除了跟踪当然是分配本身。我不确定Windows。

编辑: 以下示例分配1GB的虚拟内存

#include <stdio.h>
int main(int agrc, char **argv)
{
    void *p = malloc(1024*1024*1024);
    getc(stdin);
}

如果你跑到最高,你得到

top -p `pgrep test`
PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND
20   0 1027m  328  252 S    0  0.0   0:00.00 test

如果将malloc更改为calloc,再次运行top,则

top -p `pgrep test`
PR   NI VIRT  RES  SHR S %CPU %MEM    TIME+ COMMAND              
20   0  1027m 1.0g 328 S    0  1.3   0:00.08 test

答案 1 :(得分:1)

您是如何阅读内存使用情况的?

1)在使用char进行分配时,您为每个分配分配的内存少于例如long的分配(通常是四分之一,但它的机器)依赖) 由于程序本身外部的大多数内存使用工具都没有显示已分配的内存但实际上使用了内存,因此它只显示开销malloc()本身而不是未使用的内存,而不是malloc&#39 ; d。

更多分配,更多开销。

如果你使用每个分配的数据填充malloc&lt; d块,那么你应该得到一个非常不同的结果,所以实际使用了内存。

2)我假设您正在使用同一工具阅读该内容?尝试计算实际分配的字节数,它应该显示正确的数量,而不仅仅是&#34; malloc开销&#34;。

答案 2 :(得分:1)

1)分配内存时,每次分配都会占用请求内存的空间加上堆帧的大小。查看相关问题here

2)Windows中任何单个malloc的大小都限制为_HEAP_MAXREQ。有关详细信息和一些解决方法,请参阅this question

答案 3 :(得分:-1)

1)这可能来自内存分页并且每个页面都具有相同的大小。如果您的数据无法放入页面并且位于两页之间,我认为它将移至下一页的开头,从而在上一页的末尾创建空间损失。

2)阈值较小,因为我认为每个程序都限制在一定数量的数据中,而这些数据并不是你拥有的总最大内存量。