为什么这个 C 程序不会崩溃?
How come this C program does not crash?
这本书摘自:Understanding and Using C Pointers
If memory is re‐ peatedly allocated and then lost, then the program
may terminate when more memory is needed but malloc cannot allocate it
because it ran out of memory. In extreme cases, the operating system
may crash. This is illustrated in the following simple example:
char *chunk;
while (1) {
chunk = (char*) malloc(1000000);
printf("Allocating\n");
}
The variable chunk is assigned memory from
the heap. However, this memory is not freed before another block of
memory is assigned to it. Eventually, the application will run out of
memory and terminate abnormally.
所以我的问题是:
我有这个示例代码:
int main(int argc, char *argv[]){
char *chunk;
while (1) {
chunk = (char*) malloc(100000000);
printf("Allocating\n");
}
}
好吧,我希望我的系统 运行 内存不足,但程序保持 运行ning,我看到了文本
Allocating...
一直?
在 Linux 我猜?
仅仅因为您取回了一个指针并不意味着您实际上保留了该内存。您必须亲自触摸该页面才能成为您的页面。
内存不足时malloc
可能returnsNULL。为此添加一个检查。
while (1) {
printf("Allocating\n");
chunk = malloc(100000000);
if ( chunk == NULL )
{
printf("Memory allocation not successful.\n");
}
else
{
printf("Memory allocation successful.\n");
}
}
你运行的程序没有错。它不必异常终止。过早终止的原因是它会消耗您计算机中的所有内存,因此如果您不采取正确的措施,它就会死亡。
Linux(以及一般的 unix)对系统上的进程 运行ning 施加了一些限制。在 linux 中,所有这些限制(参见 ulimit(2) 系统调用)默认固定为 unlimited
.
当linux中的一个进程试图获得比系统拥有的更多的内存并分配剩余的虚拟内存时,内核选择一个进程(最好的候选者是试图吃掉所有内存的进程)并杀死它来恢复一些记忆。这可能就是ps为什么您阅读的文本说它异常终止。您注意到这一点是因为系统尝试交换您正在分配的所有内存并且交换器需要所有内核注意(因此您的系统似乎挂了一会儿---它没有,只需等待)
但是你可以做这样的测试:尝试限制分配给进程的虚拟内存(使用ulimit命令,参见bash(1)),所以系统可以应付内存占用程序。使用命令
$ ulimit -v 100000 # this allows for 100.000 kb of virtual memory
并重新运行 程序(它最多可以扩展到 100Mb,不能再多了)。你会看到它不会停止。它 运行 永远存在。一旦它耗尽了所有可能的内存,malloc(3) 开始 return NULL
并且该过程永远不会停止。您会看到(通过 ps(1) 命令)程序已分配到您施加的限制,不再分配,它正在 运行ning,正在消耗cpu 时间的 100%。一切都在掌控之中。我尝试了您程序的以下变体:
#include <stdlib.h>
#include <stdio.h>
char *chunk;
main()
{
int i = 0;
while (malloc(1000000)) i++;
printf("run for %i times.\n", i);
}
它计算在 运行 内存不足之前成功分配的次数,并在 stdout
上打印该数字。将 ulimit 固定为 100Mb (ulimit -v 1000000
) 后,此程序输出:
$ pru
run for 97 times.
(你会看到这小于 100Mb)所以,瞧!
这本书摘自:Understanding and Using C Pointers
If memory is re‐ peatedly allocated and then lost, then the program may terminate when more memory is needed but malloc cannot allocate it because it ran out of memory. In extreme cases, the operating system may crash. This is illustrated in the following simple example:
char *chunk;
while (1) {
chunk = (char*) malloc(1000000);
printf("Allocating\n");
}
The variable chunk is assigned memory from the heap. However, this memory is not freed before another block of memory is assigned to it. Eventually, the application will run out of memory and terminate abnormally.
所以我的问题是: 我有这个示例代码:
int main(int argc, char *argv[]){
char *chunk;
while (1) {
chunk = (char*) malloc(100000000);
printf("Allocating\n");
}
}
好吧,我希望我的系统 运行 内存不足,但程序保持 运行ning,我看到了文本
Allocating...
一直?
在 Linux 我猜?
仅仅因为您取回了一个指针并不意味着您实际上保留了该内存。您必须亲自触摸该页面才能成为您的页面。
内存不足时malloc
可能returnsNULL。为此添加一个检查。
while (1) {
printf("Allocating\n");
chunk = malloc(100000000);
if ( chunk == NULL )
{
printf("Memory allocation not successful.\n");
}
else
{
printf("Memory allocation successful.\n");
}
}
你运行的程序没有错。它不必异常终止。过早终止的原因是它会消耗您计算机中的所有内存,因此如果您不采取正确的措施,它就会死亡。
Linux(以及一般的 unix)对系统上的进程 运行ning 施加了一些限制。在 linux 中,所有这些限制(参见 ulimit(2) 系统调用)默认固定为 unlimited
.
当linux中的一个进程试图获得比系统拥有的更多的内存并分配剩余的虚拟内存时,内核选择一个进程(最好的候选者是试图吃掉所有内存的进程)并杀死它来恢复一些记忆。这可能就是ps为什么您阅读的文本说它异常终止。您注意到这一点是因为系统尝试交换您正在分配的所有内存并且交换器需要所有内核注意(因此您的系统似乎挂了一会儿---它没有,只需等待)
但是你可以做这样的测试:尝试限制分配给进程的虚拟内存(使用ulimit命令,参见bash(1)),所以系统可以应付内存占用程序。使用命令
$ ulimit -v 100000 # this allows for 100.000 kb of virtual memory
并重新运行 程序(它最多可以扩展到 100Mb,不能再多了)。你会看到它不会停止。它 运行 永远存在。一旦它耗尽了所有可能的内存,malloc(3) 开始 return NULL
并且该过程永远不会停止。您会看到(通过 ps(1) 命令)程序已分配到您施加的限制,不再分配,它正在 运行ning,正在消耗cpu 时间的 100%。一切都在掌控之中。我尝试了您程序的以下变体:
#include <stdlib.h>
#include <stdio.h>
char *chunk;
main()
{
int i = 0;
while (malloc(1000000)) i++;
printf("run for %i times.\n", i);
}
它计算在 运行 内存不足之前成功分配的次数,并在 stdout
上打印该数字。将 ulimit 固定为 100Mb (ulimit -v 1000000
) 后,此程序输出:
$ pru
run for 97 times.
(你会看到这小于 100Mb)所以,瞧!