linux new 释放内存吗,【十问Linux虚拟内存管理】第五问:free 的内存真的释放了吗(还给 OS ) ?...

0818b9ca8b590ca3270a3433284dd417.png

0818b9ca8b590ca3270a3433284dd417.png

第五问来啦!

5

free

的内存真的释放了吗(还给 OS ) ?

前面所有例子都有一个很严重的问题,就是分配的内存都没有释放,即导致内存泄露。

原则上所有 malloc/new 分配的内存,都需 free/delete 来释放。但是, free 了的内存真的释放了吗?

要说清楚这个问题,可通过下面例子来说明。

(1)    初始状态

如图 (1) 所示,系统已分配 ABCD 四块内存,其中 ABD 在堆内分配, C使用 mmap 分配。为简单起见,图中忽略了如共享库等文件映射区域的地址空间。

(2)    E=malloc(100k)

分配 100k 内存,小于 128k ,从堆内分配,堆内剩余空间不足,扩展堆顶 (brk) 指针。

(3)    free(A)

释放 A 的内存,在 glibc 中,仅仅是标记为可用,形成一个内存空洞 ( 碎片 ) ,并没有真正释放。如果此时需要分配 40k 以内的空间,可重用此空间,剩余空间形成新的小碎片。

0818b9ca8b590ca3270a3433284dd417.png

(4)    free(C)

C 空间大于 128K ,使用 mmap 分配,如果释放 C ,会调用 munmap系统调用来释放,并会真正释放该空间,还给 OS ,如图 (4) 所示。

(5)    free(D)

与释放 A 类似,释放 D 同样会导致一个空洞,获得空闲空间,但并不会还给 OS 。此时,空闲总空间为 100K ,但由于虚拟地址不连续,无法合并,空闲空间无法满足大于 60k 的分配请求。

(6)    free(E)

释放 E ,由于与 D 连续,两者将进行合并,得到 160k 连续空闲空间。同时 E 是最靠近堆顶的空间, glibc 的 free 实现中,只要堆顶附近释放总空间(包括合并的空间)超过 128k ,即会调用 sbrk(-SIZE) 来回溯堆顶指针,将原堆顶空间还给OS ,如图 (6) 所示。而堆内的空闲空间还是不会归还 OS 的。

0818b9ca8b590ca3270a3433284dd417.png

由此可见

1.  malloc 使用 mmap 分配的内存 ( 大于 128k) , free 会调用 munmap 系统调用马上还给 OS ,实现真正释放。

2.  堆内的内存,只有释放堆顶的空间,同时堆顶总连续空闲空间大于 128k 才使用sbrk(-SIZE) 回收内存,真正归还 OS 。

3.  堆内的空闲空间,是不会归还给 OS 的。

【往期精彩回顾】

0818b9ca8b590ca3270a3433284dd417.png

0818b9ca8b590ca3270a3433284dd417.png

0818b9ca8b590ca3270a3433284dd417.png

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值