问一个底层问题, malloc 申请得到的内存后,再 free 释放它的时候,操作系统会立即收回那块内存吗??

2015-03-29 16:55:24 +08:00
 wind3110991

如题,然后下面是一个朋友给我的解答:
1)C库老老实实地待在硬盘里,没法管这事。free()是库函数,没错。可这就给许多人错觉,以为,C自己把这事给办了。空间回收和空间分配一样,涉及到两块空间:虚拟空间与物理空间。虚拟空间是进程私有的,这没事,进程可以自行了断。但物理空间一共就一块,所有的进程都共用它。如果让每个进程自行做垃圾回收,那不就乱了套了?因此,我想象,库函数free()只是通知“可以回收啦”而没有真正回收空间。
2)当虚存释放空间时,如果系统立即做实存的回收,那会把系统累死。整个系统的运作效率大大降低。因此,现代系统的垃圾回收都有一些算法。这个好比你家门口的垃圾袋,并不是你放出去,小区清洁工立即拿走的。没有一个清洁工能对小区所有业主做到这样的服务,除非她是超人或机器猫。如果系统足够聪明,能识别某进程已经僵死并回收了它所占的空间,那为啥还剩下它的PCB呢?

但是还是不太懂,而且这个不一定是唯一答案,有这方面专业的大神来解答下吗?

4770 次点击
所在节点    C
30 条回复
wind3110991
2015-03-29 23:18:11 +08:00
@jonah

结合自己写了段测试程序:
#include<stdio.h>
int main(){
unsigned char *p = (unsigned char*)malloc(4*sizeof(unsigned char));
memset(p,0,4);
strcpy((char*)p,"Hello guys! ");
printf("%s",p);
free(p);
printf("%s",p);
return 0;
}

输出时打印了两次p的字符串

然后google了c库里free的源码:

void free(void* ap)
{
Header *bp,*p,*prev;
bp=(Header*)ap-1;
for(prev=memptr,p=memptr->s.next;
(p!=bp) && (p!=memptr);prev=p,p=p->next);
if(p!=bp) return;
prev->s.freesize+=p->s.usedsize+p->s.freesize;
prev->s.next=p->s.next;
memptr=prev;
}

应该按理来说就是这个意思,os涉及物理储存的部分,c函数库是无法进行操作的,申请一块内存后,在进程结束前,c库无法在物理内存层面对内存进行直接管理
但是始终有些困惑= =感觉半懂半懵, 我还是再研究下
HowardMei
2015-03-29 23:20:34 +08:00
记忆可能不准,仅供参考:

Stack由OS统一管理自动分配[地址有序],Heap比较宽松自主管理[地址乱序]

不同语言对Stack/Heap使用不一样,不过基本上malloc都通过OS来操作,而free却未必会把
空间直接还给OS,也许只是按特定方式收集标记起来,适时一起归还,也许直接就归还了,
因为OS对内存管理是按照Page为单位的,你如果要归还的空间不满一个Page,OS无法处理。

具体到C语言,也是一样,要看库怎么写的,但有OS的情况下,malloc最小申请一个Page,
而free也通常不会直接释放,而是收集标记后再交给malloc归还给OS
bcxx
2015-03-29 23:28:07 +08:00
wind3110991
2015-03-29 23:46:53 +08:00
@bcxx 大神!!那么请问下如果在同一个编译模块下,我在free了一块内存(我叫他为Page1)后再次malloc,那么之前os会有可能分配之前申请到的那一块相同的内存(Page1)吗?是不是free后被标记就暂时无法再被分配了
Andiry
2015-03-30 00:03:39 +08:00
@wind3110991 当然可能,而且应该如此,减少page fault
wind3110991
2015-03-30 00:34:05 +08:00
@Andiry 谢谢!
wind3110991
2015-03-30 00:34:39 +08:00
@tonyluj 感觉内核代码还不适合我研究啊,现在刚刚入门
wind3110991
2015-03-30 00:34:50 +08:00
@fenjuly bingo~
hyuwang
2015-03-30 02:38:55 +08:00
mark下 还挺好奇的
写C的时候是直接malloc完乖乖free没有想很多
编MIPS的的时候对stack的操作是即时的,用完即pop,不知道可不可以类推到C
qq446015875
2015-03-30 13:34:21 +08:00
@DiveIntoEyes thanks!我看了下你发的链接,写的很清楚啊

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/180130

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX