C中程序的最大堆大小是固定的还是我继续进行malloc-ing它会在某个时刻开始溢出?
代码:
while(connectionOK) //connectionOK is the connection with server which might be forever
{
if(userlookup_IDNotFound(userID))
user_struct* newuser = malloc(getsize(user_struct));
setupUserAccount(newuser);
}
如果重要的话,我在ubuntu / linux中使用gcc。 我知道像getrlimit这样的东西,但不确定它是否给出了堆大小。虽然它确实为输入参数中的一个选项提供了默认堆栈大小。 另外valgrind可能是一个很好的工具,如how to get Heap size of a program所示,但是如果存在堆溢出,我想动态打印错误消息。 我的理解是在创建进程的开始时OS分配的进程地址空间(实际上允许使用整个内存)但是我不确定它是否在请求时动态地给出了更多的物理内存为了额外的记忆。
答案 0 :(得分:3)
堆永远不会溢出它只是在某一点耗尽内存(通常在malloc()
返回NULL
时)所以要检测内存不足,只需检查malloc()
的返回值调用
if (newuser == NULL)
{
printf("OOM\n");
exit(1); /* exit if you want or can't handle being OOM */
}
malloc()
内部将从操作系统请求更多内存,因此它会动态扩展,因此它不是真正固定的大小,因为它会将页面返回给它不再需要的操作系统以及在任何给定时间请求更多它需要他们。
答案 1 :(得分:2)
从技术上讲,malloc
在大多数系统上分配的不是内存,而是地址空间。在现代系统上,您可以使用malloc轻松分配几PB的地址空间,malloc可能总是返回非空指针。这背后的原因是,大多数操作系统实际上只在主动修改一块地址空间时执行内存分配。只要它不受影响,操作系统就会记下过程地址空间的某个区域已被有效保留以备将来使用。
这种行为被称为“内存过度使用”,在维护Linux系统时非常重要。如果可能发生,那么分配的内存比可用的内存多一段时间,然后某些程序实际上会写入一些过度使用的内存。然后发生的是,所谓的“内存杀手”(OOM杀手)将继续横冲直撞并杀死它认为最适合的那些进程;不幸的是,它通常是那些在任何情况下都不想放松的过程。众所周知,数据库是OOM杀手的主要目标之一。
因此,强烈建议在高可用性Linux机器上切换内存过量使用。禁用禁用的内存过量使用后,每个地址空间请求都必须由内存支持。在这种情况下,如果请求无法填满,malloc实际上将返回0。
答案 2 :(得分:1)
在某些时候,当系统内存不足时,malloc()
将返回NULL
。然后,当你试图取消引用时,你的程序将中止执行。
看看malloc(SIZE_MAX)
几次会发生什么: - )