终止程序是否以与 free() 相同的方式回收内存?

2024-03-20

I saw 这个答案 https://stackoverflow.com/a/6347182/8183900关于堆栈溢出问题,该问题表明在 C 程序的最后释放内存实际上是有害的,因为它将不会再次使用的变量移动到系统内存中。

我很困惑为什么 C 中的 free() 方法会做与操作系统在程序结束时回收堆不同的事情。

有谁知道 free() 和终止在内存管理方面是否存在真正的区别,如果有的话操作系统如何不同地对待这两者?

e.g.

这两个短节目之间会发生什么不同的事情吗?

void main() {
    int* mem = malloc(1);
    return 0;
}
void main() {
    int* mem = malloc(1);
    free(mem);
    return 0;
}

不,终止程序,就像exit or abort,不会以与free. Using free当操作系统丢弃由malloc and free.

exit有一些复杂性,因为它不会立即终止程序。现在,我们只考虑立即终止程序的影响,稍后再考虑并发症。

In a general-purpose multi-user operating system, when a process is terminated, the operating system releases the memory it was using to make it available for other purposes.1 In large part, this simply means the operating system does some accounting operations.

相反,当您调用free,程序内的软件运行,它必须查找您正在释放的内存的大小,然后将有关该内存的信息插入到它正在维护的内存池中。可能有数千或数万(或更多)此类分配。释放所有数据的程序可能必须执行数千次调用free。然而,最终,当程序退出时,所产生的所有变化free将会消失,因为操作系统将丢弃有关该内存池的所有数据 - 所有数据都位于操作系统不保留的内存页中。

所以,在这方面,您链接到的答案 https://stackoverflow.com/a/6347182/8183900是正确的,调用free是一种浪费。而且,正如它所指出的,需要遍历程序中的所有数据结构来获取其中的指针,以便可以释放它们指向的内存,这会导致所有这些数据结构在被换出时被读入内存到磁盘。对于大型程序,可能需要大量的时间和其他资源。

另一方面,尚不清楚是否可以轻松避免多次调用free。这是因为释放内存并不是终止程序必须清理的唯一事情。程序可能想要将最终数据写入文件或将最终消息发送到网络连接。此外,程序可能没有直接建立所有这些上下文。大多数大型程序都依赖于软件层,每个软件包可能都建立了自己的上下文,并且通常没有提供任何方式来告诉其他软件“我想现在退出。完成有价值的上下文,但跳过所有内存释放。”因此,所有所需的清理任务可能与空闲内存任务交织在一起,并且可能没有好方法来理清它们。

通常应编写软件,以便在程序突然中止时不会发生任何可怕的情况(因为这种情况可能是由于断电而发生的,而不仅仅是故意的用户操作)。但即使程序可能能够容忍中止,优雅退出仍然有价值。

回到exit,调用 Cexit例程不会立即退出程序。退出处理程序(注册为atexit) 被调用,流缓冲区被刷新,流被关闭。您调用的任何软件库可能已经设置了自己的退出处理程序,以便它们可以在程序退出时完成。因此,如果您想确保程序中使用的库没有调用free当你结束程序时,你必须调用abort, not exit。但通常更喜欢优雅地结束程序,而不是中止。呼唤abort不会调用退出处理程序、刷新流、关闭流或执行其他结束代码exit确实——当程序调用时数据可能会丢失abort.

Footnote

1 Releasing memory does not mean it is immediately available for other purposes. The specific result of this depends on each page of memory. For example:

  • 如果内存与其他进程共享,则它们仍然需要该内存,因此释放此进程使用的内存只会减少使用该内存的进程数量。它不能立即用于任何其他用途。
  • 如果内存未被任何其他进程使用,但包含从磁盘上的文件映射的数据,则操作系统可能会在需要时将其标记为可用,但暂时将其保留。这是因为您可能会再次运行相同的程序,如果数据仍在内存中就好了,那么为什么不将其保留在原处以防万一呢?这些数据甚至可能被使用同一文件的不同程序使用。 (例如,许多程序可能使用相同的共享库。)
  • 如果内存没有被任何其他进程使用,并且只是被程序用作工作区,而不是从文件映射,那么系统可能会将其标记为立即可用,并且不包含任何有用的内容。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

终止程序是否以与 free() 相同的方式回收内存? 的相关文章

随机推荐

  • 如何构建一个同时暴露rest和soap服务的Spring Boot jar

    我一直在考虑为开发人员社区构建一个测试 jar 以便公开 API 的下一个版本的预览 让存根返回具有精确格式的预期响应等 我们确实有 REST 和 SOAP API 我想构建 REST 服务不会有任何问题 因为网络上充斥着示例 令人惊讶的是
  • 方面未在 Spring 中执行

    我正在编写一个几乎完全受登录保护的网站 我正在使用 Spring Security 不过 有些页面不受保护 主页 登录页面 注册页面 忘记密码页面 我想要实现的是 如果用户在访问这些非安全页面时未登录 正常显示它们 如果用户已经登录 则重定
  • Firefox41 中的 GWT 重复编码 URL 中的令牌

    包含地点 活动等的 Gwt 应用程序 有没有其他人遇到过 Firefox 41 0 在 URL 标记中重复编码 看起来就像调用 PlaceController goto 时一样 循环直到崩溃 令牌以管道开头 search advanced
  • C# NTLM 哈希计算器

    我最近开始学习C 我尝试用这种语言生成 NTLM 哈希 但找不到为我执行此操作的函数 在 python 3 x 中我会导入hashlib并计算它hashlib new md4 Hello World encode utf 16le 我在 C
  • 用C#以编程方式打开位于计算机中的Word文档

    我正在使用 WinForms 我有一个带有按钮的表单 目标 单击按钮时 打开 Word 文档 文件路径被硬编码到程序中 我不希望用户必须找到Word文档 问题 我收到此错误消息 当我编写代码时 应用程序 下出现红色错误行 private v
  • 未指定 APN?

    我正在创建 httpConnection 但运行应用程序时会出现以下异常 java io IOException 未指定 APN 我认为查看开发人员知识库文章 链接可以解决您的问题 另请参阅此示例代码 private static Stri
  • Eclipse 中的 TestNG,引用未定义的变量 env.DOMAIN_PATH

    当我尝试使用 TestNG 在 Eclipse 中运行单元测试时 我刚刚收到错误 错误消息是 Reference to undefined variable env DOMAIN PATH 但是当我在Intellij或maven中运行它时
  • 使用 jsonpickle 从文件保存和加载对象

    我有以下简单方法使用 jsonpickle 将 python 对象写入文件 def json serialize obj filename use jsonpickle True f open filename w if use jsonp
  • 如何用矩阵的一些不连续的行和列形成子矩阵

    我有一个 10 x 10 矩阵 我想从这个主矩阵形成一个子矩阵 使用除第一 第二和第八列和行之外的所有行和列 我知道 Part 可以用来形成子矩阵 但这些示例主要是关于仅使用连续的行和列形成子矩阵 如果这是你的矩阵 tst RandomIn
  • 使用 ECS 时保护来自 EC2 实例的出站流量规则

    即使我在私有子网中创建 EC2 实例 如果我想将它们注册到 ECS 集群 它们也必须能够将流量发送到 Internet 我正在使用 NAT 网关来执行此操作 但我仍然感到不安全 因为实例可以在被接管时将私人信息发送到任何地方 我可以用于实例
  • apache从非www重定向到www

    我有一个网站似乎没有从非 www 重定向到 www 我的Apache配置如下 RewriteEngine On re direct to www RewriteCond http host www example com nc Rewrit
  • C# - 混合汇编(C++/CLI、DirectX 本机)交互(32/64 位)

    我有一个相关问题这个问题 https stackoverflow com questions 2963809 anycpu x86 x64 for c application and its c cli dependency 两名球员 C
  • 检查重复 ID 的 Html javascript 代码

    如何在javascript中检查包含重复id的标签 尝试这个 var nodes document querySelectorAll id var ids var totalNodes nodes length for var i 0 i
  • 编辑“prefers-color-scheme”值以强制使用深色模式

    我花了几个小时寻找解决方案 在线和在 Chrome 控制台中 但没有成功 实现暗模式的 正确 方法是使用带有 prefers color scheme 参数的媒体查询 body color fff media prefers color s
  • Heroku 上的 Django - 缺少静态文件 manifest.json 文件

    我正在尝试在 Heroku 上启动 Django 我环顾了 Stack Overflow 尝试了不同的方法 但我无法弄清楚 它看起来与 Django 上与 staticfiles 问题相关的所有问题类似 不幸的是我不知道问题出在哪里 我的项
  • Array.prototype.includes 中的错误?

    我遇到了奇怪的行为Array prototype includes在一种边缘情况下 鉴于Array prototype includes适用于绑定上下文 人们可能会像这样使用它 这是有效的 expect Array prototype in
  • 连接 Wi-Fi 网络时如何使用蜂窝数据?

    我期待在连接 Wi Fi 时使用蜂窝数据 Yi行车记录仪的工作原理是这样的 易相机制作软AP iOS 或 Android 手机连接 Wi Fi YI和Phone之间建立内部网络 一般情况下 手机不能上网 但是 在Yi网络中 手机可以使用互联
  • 从“选择应用程序”列表中隐藏 NFC 应用程序/禁用通过外部 NFC 意图启动

    我目前正在为 Android 编写几个支持 NFC 的应用程序 并想知道如何阻止我的应用程序出现在 选择应用程序 列表中 该列表在从启动器或非 NFC 应用程序扫描标签时打开 我只希望我的应用程序能够在打开时读取标签 我当前的意图过滤器
  • 软件包:cx_Oracle for Python 3.5,windows64 位。甲骨文11.2.0.1.0

    我正在尝试在我的 Windows PC 上安装 cx Oracle 我在命令提示符下运行了以下命令 pip install cx Oracle 这给了我以下错误 Collecting cx Oracle Could not find a v
  • 终止程序是否以与 free() 相同的方式回收内存?

    I saw 这个答案 https stackoverflow com a 6347182 8183900关于堆栈溢出问题 该问题表明在 C 程序的最后释放内存实际上是有害的 因为它将不会再次使用的变量移动到系统内存中 我很困惑为什么 C 中