【发布时间】: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;
}
一般来说,我更喜欢在返回之前释放内存,因为对性能的影响很小,而且它有助于自动化工具检测内存泄漏。也就是说,这里的性能/最佳实践对我来说不太清楚,因为在守护进程上运行这些工具几乎没有意义。这引出了两个问题:
- 在返回之前释放父进程的内存(例如
*buf)会影响子进程的性能吗?我认为通过实现写入时复制的方式可能会有一些(正面或负面)。 - 父母
free剩余资源是否被认为是一种好的做法?
【问题讨论】:
-
这实际上是一个非常有趣的问题。
freeing 内存可能会导致它被复制(取决于分配器的实现方式,但我知道的大多数内存都在分配的内存之前存储元数据,这将由free更新),具有讽刺意味的是,它将使用增加额外的物理内存。 -
@AndrewSun 是的,我也反复讨论过——我目前的想法是它实际上影响很小,因为内核可以避免复制,如果父级释放(因为大多数内核只复制页表来启动),但我不确定根据适用标准会产生什么影响,和/或内核是否真的这样做。
-
这将取决于 libc 内存分配器的实现方式以及分配的大小;一个智能分配器可能会跳过元数据并直接将内存返回给内核(跳过副本),如果它可以释放整个页面,一个不太智能的分配器可能会触摸元数据然后将内存返回给内核(这会做一个副本,然后释放它)