C malloc 和免费
C malloc and free
有人告诉我,如果您执行 malloc(),但不执行 free(),内存将一直占用,直到重新启动。好吧,我当然测试过它。一个非常简单的代码:
#include <stdlib.h>
int main(void)
{
while (1) malloc(1000);
}
我在 Task Manager (Windows 8.1) 看过它。
好吧,这个程序真的很快就占用了 2037.4 MB,而且就一直这样。我知道这可能是 Windows 限制了程序。
但这是奇怪的部分:当我关闭控制台时,内存使用百分比下降了,尽管我被告知这是不应该的!
调用 free 是否多余,因为操作系统无论如何都会释放它?
(here的问题是相关的,但没有完全回答我是否应该免费。)
建议在分配完内存后调用free
,因为稍后在程序中可能需要此内存space,如果没有没有用于新分配的内存 space。
您应该始终为您的 code.If windows 寻求可移植性来释放这个 space,可能其他操作系统没有。
操作系统中的每个进程都有有限的可寻址内存,称为进程地址Space。如果您分配了大量内存并且最终分配了所有可用于该进程的内存,则 malloc 将失败并且 return NULL。并且您将无法再为该进程分配内存。
在 Windows,一个 32 位进程只能分配 2048 兆字节,因为那里有多少地址。部分内存可能被 Windows 保留,因此总数字较低。 malloc
returns 失败时为空指针,这很可能会在此时发生。您可以像这样修改您的程序以查看:
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
int counter = 0;
while (1) {
counter++;
if (malloc(1000) == NULL) {
printf("malloc failed after %d calls\n", counter);
return 0;
}
}
}
现在你应该得到这样的输出:
$ ./mem
malloc failed after 3921373 calls
当一个进程终止或从外部终止时(就像您通过任务管理器杀死它一样),该进程分配的所有内存都会被释放。操作系统管理哪些内存属于哪个进程,因此可以在进程终止时释放进程的内存。然而,操作系统不知道每个进程如何使用它从操作系统请求的内存,并且取决于进程告诉它何时不再需要内存块。
那你为什么需要free()
?好吧,这只会在程序终止时发生,并且不会区分您仍然需要的内存和您不再需要的内存。当您的进程在做复杂的事情时,它通常会不断地为自己的计算分配和释放内存。使用 free()
显式释放内存很重要,否则您的进程可能在某个时候不再能够分配新内存并崩溃。尽可能释放内存也是一种很好的编程习惯,这样您的进程就不会不必要地占用大量内存。相反,其他进程可以使用该内存。
对于所有重要的 OS,进程资源在进程终止时由 OS 回收。
除非有特定且最重要的理由在终止时显式释放内存,否则您不需要这样做,至少出于以下原因您不应尝试:
1) 您需要编写代码来执行、测试和调试。为什么要这样做,如果 OS 可以做到呢?这不仅是多余的,而且会降低质量,因为您的显式资源释放永远不会像 OS 发布之前已经进行的测试那样多。
2) 对于一个复杂的应用程序,有一个 GUI 和许多子系统和线程,关闭时干净地释放内存几乎是不可能的,这导致:
3) 许多库开发人员已经放弃了 'you must explicitly release blah... ' 的信条,因为复杂性会导致库永远不会被发布。许多报告未发布,(但没有丢失),内存到 valgrid,并且使用不透明的库,你对此无能为力。
4) 不得释放任何 运行ning 线程正在使用的内存。要在多线程应用程序中安全地释放所有此类内存,您必须确保所有进程线程都已停止并且不能再次 运行。用户代码没有执行此操作的工具,OS 有。因此,在此类应用程序中,不可能以任何一种安全的方式明确地从用户代码中释放内存。
5) OS 可以大块释放进程内存 - 比在 C 管理器中乱搞几十个子分配要快得多。
6) 如果进程因为内存管理问题失败而被终止,多次调用 free() 根本无济于事。
7) 许多老师和教授说你必须显式地释放内存,所以这显然是一个糟糕的计划。
有人告诉我,如果您执行 malloc(),但不执行 free(),内存将一直占用,直到重新启动。好吧,我当然测试过它。一个非常简单的代码:
#include <stdlib.h>
int main(void)
{
while (1) malloc(1000);
}
我在 Task Manager (Windows 8.1) 看过它。
好吧,这个程序真的很快就占用了 2037.4 MB,而且就一直这样。我知道这可能是 Windows 限制了程序。
但这是奇怪的部分:当我关闭控制台时,内存使用百分比下降了,尽管我被告知这是不应该的!
调用 free 是否多余,因为操作系统无论如何都会释放它?
(here的问题是相关的,但没有完全回答我是否应该免费。)
建议在分配完内存后调用free
,因为稍后在程序中可能需要此内存space,如果没有没有用于新分配的内存 space。
您应该始终为您的 code.If windows 寻求可移植性来释放这个 space,可能其他操作系统没有。
操作系统中的每个进程都有有限的可寻址内存,称为进程地址Space。如果您分配了大量内存并且最终分配了所有可用于该进程的内存,则 malloc 将失败并且 return NULL。并且您将无法再为该进程分配内存。
在 Windows,一个 32 位进程只能分配 2048 兆字节,因为那里有多少地址。部分内存可能被 Windows 保留,因此总数字较低。 malloc
returns 失败时为空指针,这很可能会在此时发生。您可以像这样修改您的程序以查看:
#include <stdlib.h>
#include <stdio.h>
int main(void)
{
int counter = 0;
while (1) {
counter++;
if (malloc(1000) == NULL) {
printf("malloc failed after %d calls\n", counter);
return 0;
}
}
}
现在你应该得到这样的输出:
$ ./mem
malloc failed after 3921373 calls
当一个进程终止或从外部终止时(就像您通过任务管理器杀死它一样),该进程分配的所有内存都会被释放。操作系统管理哪些内存属于哪个进程,因此可以在进程终止时释放进程的内存。然而,操作系统不知道每个进程如何使用它从操作系统请求的内存,并且取决于进程告诉它何时不再需要内存块。
那你为什么需要free()
?好吧,这只会在程序终止时发生,并且不会区分您仍然需要的内存和您不再需要的内存。当您的进程在做复杂的事情时,它通常会不断地为自己的计算分配和释放内存。使用 free()
显式释放内存很重要,否则您的进程可能在某个时候不再能够分配新内存并崩溃。尽可能释放内存也是一种很好的编程习惯,这样您的进程就不会不必要地占用大量内存。相反,其他进程可以使用该内存。
对于所有重要的 OS,进程资源在进程终止时由 OS 回收。
除非有特定且最重要的理由在终止时显式释放内存,否则您不需要这样做,至少出于以下原因您不应尝试:
1) 您需要编写代码来执行、测试和调试。为什么要这样做,如果 OS 可以做到呢?这不仅是多余的,而且会降低质量,因为您的显式资源释放永远不会像 OS 发布之前已经进行的测试那样多。
2) 对于一个复杂的应用程序,有一个 GUI 和许多子系统和线程,关闭时干净地释放内存几乎是不可能的,这导致:
3) 许多库开发人员已经放弃了 'you must explicitly release blah... ' 的信条,因为复杂性会导致库永远不会被发布。许多报告未发布,(但没有丢失),内存到 valgrid,并且使用不透明的库,你对此无能为力。
4) 不得释放任何 运行ning 线程正在使用的内存。要在多线程应用程序中安全地释放所有此类内存,您必须确保所有进程线程都已停止并且不能再次 运行。用户代码没有执行此操作的工具,OS 有。因此,在此类应用程序中,不可能以任何一种安全的方式明确地从用户代码中释放内存。
5) OS 可以大块释放进程内存 - 比在 C 管理器中乱搞几十个子分配要快得多。
6) 如果进程因为内存管理问题失败而被终止,多次调用 free() 根本无济于事。
7) 许多老师和教授说你必须显式地释放内存,所以这显然是一个糟糕的计划。