我正在尝试用malloc进行实验,看看是否可以分配所有可用的内存。
我使用了以下简单的程序,并有几个问题:
int main(void)
{
char * ptr;
int x = 100;
while(1)
{
ptr = (char *) malloc(x++ * sizeof(char) / 2);
printf("%pn",ptr);
}
return 0;
}
1(为什么当使用较大的数据类型(int,无符号长整整,长双精度(时,进程会使用更少的内存,但对于较小的数据类型(int,char(,它会使用更多?
2(运行程序时,它将在达到一定数量后停止分配内存(在Windows 7上为~592mb 64,8GB RAM交换文件设置为系统管理(。 如果显示 0,则打印的输出表示 NULL。 为什么它在达到此阈值后停止分配内存,并且不耗尽系统内存并交换?
我在下面的帖子中发现有人在尝试与我相同的事情,但差异他们没有看到内存使用的任何差异,但我是。内存泄漏使用 malloc 失败
我已经在 Linux 内核 2.6.32-5-686 上尝试了代码,结果类似。
任何帮助和解释将不胜感激。
谢谢
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 -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(使用 char
进行分配时,每次分配分配的内存比使用long
少(通常是四分之一,但这取决于机器(由于程序本身外部的大多数内存使用工具不显示分配的内存,而是实际使用的内存,因此它只会显示malloc((本身使用的开销,而不是malloc'd的未使用内存。
分配,更多的开销。
如果用每个分配的数据填充 malloc'd 块,以便实际使用内存,则应该得到非常不同的结果。
2(我假设您是从同一个工具阅读的?尝试计算您实际分配的字节数,它应该显示正确的数量,而不仅仅是"malloc 开销"。
1( 分配内存时,每次分配都会占用请求的内存空间加上堆帧的大小。 在此处查看相关问题
2( 任何单个 malloc 的大小在 Windows 中限制为 _HEAP_MAXREQ。 有关详细信息和一些解决方法,请参阅此问题。
1(这可能是因为内存是分页的,并且每个页面都有相同的大小。如果您的数据无法容纳在页面中并且位于两页之间,我认为它会移动到下一页的开头,从而在上一页的末尾造成空间损失。
2(阈值较小,因为我认为每个程序都限制在一定数量的数据上,这不是您拥有的总最大内存。