【问题标题】:Should a daemonising parent free() memory after forking its child?一个守护进程的父进程是否应该在分叉其子进程后释放()内存?
【发布时间】:2019-10-14 12:25:00
【问题描述】:

假设我们有一些这样的代码:

int main() {
    FILE *f_conf = fopen("conf.conf");
    /* File Open Error Handling */

    char *buf = malloc(128);
    /* Malloc Error Handling */

    fgets(buf, 128, f_conf);
    fclose(f_conf);

    pid_t pid = fork()
    /* Fork Error Handling */

    if (pid) {
        free(buf); /* Should this free be called? */
        return 0;
    }

    while (1) {
        /* Do Stuff */
    }

    return 0;
}

一般来说,我更喜欢在返回之前释放内存,因为对性能的影响很小,而且它有助于自动化工具检测内存泄漏。也就是说,这里的性能/最佳实践对我来说不太清楚,因为在守护进程上运行这些工具几乎没有意义。这引出了两个问题:

  1. 在返回之前释放父进程的内存(例如*buf)会影响子进程的性能吗?我认为通过实现写​​入时复制的方式可能会有一些(正面或负面)。
  2. 父母free剩余资源是否被认为是一种好的做法?

【问题讨论】:

  • 这实际上是一个非常有趣的问题。 freeing 内存可能会导致它被复制(取决于分配器的实现方式,但我知道的大多数内存都在分配的内存之前存储元数据,这将由free 更新),具有讽刺意味的是,它将使用增加额外的物理内存。
  • @AndrewSun 是的,我也反复讨论过——我目前的想法是它实际上影响很小,因为内核可以避免复制,如果父级释放(因为大多数内核只复制页表来启动),但我不确定根据适用标准会产生什么影响,和/或内核是否真的这样做。
  • 这将取决于 libc 内存分配器的实现方式以及分配的大小;一个智能分配器可能会跳过元数据并直接将内存返回给内核(跳过副本),如果它可以释放整个页面,一个不太智能的分配器可能会触摸元数据然后将内存返回给内核(这会做一个副本,然后释放它)

标签: c fork posix daemon


【解决方案1】:

我认为将 thing 的分配限制在它有效的可执行区域是一种很好的做法。对我来说,免费是文档的一部分——这个 东西 不再有效或无法访问。在所有事情的编程中,简洁会产生清晰;清晰的程序可以改进和优化;不连贯的不能。

就跨叉的性能而言,如果您要测量页面缓存效果,那么您可能处于一个非常黑暗的地方。从根本上说,进程的页面将指向同一个底层页面;如果一个人放弃了该页面,另一个人将免费获得它[如果 refcount == 1,复制没有意义]。实际上,所发生的只是一些链表节点被更新,而你无法真正衡量它。

也就是说,如果您要分配整张 DVD 或其他东西,是的,您可以考虑将其映射为共享

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2016-06-12
    • 2016-09-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多