free 内存的时候,内存是否会还给 OS 重新分配?

2017-11-24 10:35:19 +08:00
 jiang1234321

malloc 内存用于存放 TCP 连接收到的数据,在接收完成后,free 内存,结果在 top 和 free -m 指令的显示下,进程的内存并没有减少,反而随着连接的增加一直增加,free 的内存不会归还给 OS 吗?

5019 次点击
所在节点    Linux
26 条回复
wwqgtxx
2017-11-24 10:37:31 +08:00
取决于 glibc 或者是其他 malloc 提供者的实现
debuggerx
2017-11-24 10:55:35 +08:00
一般是 glibc 会复用 free 的内存,以尽量减少内存碎片的产生。。如果 free 一点就还给 os 一点内存很快就没法用了
seaswalker
2017-11-24 11:00:31 +08:00
malloc 这种分配器实现应该会维护一个分配链表,free 之后会将内存重新置为可分配状态,应该不会还给 OS,我觉得
VYSE
2017-11-24 11:01:48 +08:00
现有用户态 malloc 实现通常会向 kernel 申请一段内存自己优化管理,释放后会带来空隙,也就是碎片化
当然空隙以后被填上,开销比每次申请小很多
momocraft
2017-11-24 11:10:37 +08:00
不应该永远不还 很可能不立即还
noli
2017-11-24 11:17:21 +08:00
@momocraft 这个描述最简洁。
facetest
2017-11-24 11:17:30 +08:00
一般不会,这样做效率太低
hxndg
2017-11-24 11:22:47 +08:00
我记得当年我还就这个问题写过一篇博客...下面这个是我当时搜到的资料,你可以看看.
https://www.ibm.com/developerworks/linux/library/l-memory/
lijiangming
2017-11-24 11:23:28 +08:00
看到这个问题,立马取找出源码看了有一会了,glibc\malloc\malloc.c,里面有引用 arena.h,恰好之前也在 cii 中看到过 arena 得实现,好像是有维护一个已释放的内存链表,好像这是为了避免在相同进程中使用同一内存地址,细看还得花时间^o^
jiang1234321
2017-11-24 12:26:39 +08:00
@debuggerx 64*1024 个字节呢,不少吧
jiang1234321
2017-11-24 12:27:21 +08:00
@momocraft 没有新的连接建立的时候,内存也一直都没有释放,一直都不变
jiang1234321
2017-11-24 12:28:51 +08:00
@lijiangming 也就是说内存已经释放了,但是 OS 不会再一次分配给这个进程?
jiang1234321
2017-11-24 12:30:03 +08:00
@hxndg 方便贴出来博客的连接吗?一大段英文 get 不到重点
jiang1234321
2017-11-24 12:31:11 +08:00
@wwqgtxx linux 平台的实现应该都是一样的吧
debuggerx
2017-11-24 12:34:32 +08:00
lijiangming
2017-11-24 14:01:42 +08:00
@jiang1234321 好像我说的记得有点问题,应该 arena 就是内存池,会返回重复得内存地址,我测试
int *a = (double *)malloc(sizeof(double));
free(a);
int *b = (double *)malloc(sizeof(double));
free(b);
在 ubuntu16.4 64 位下测试结果 a 和 b 指向相同地址
lijiangming
2017-11-24 14:02:27 +08:00
@jiang1234321 复制错了,sizeof(int); 你可以测试一下
hxndg
2017-11-24 14:04:22 +08:00
@jiang1234321
额,不好意思啊,我博客太多隐私的东西了.
简单来说就是不立刻还给系统,malloc 会自己保存一个很大的串来进行管理.
有专门的函数控制这个,你可以搜索一下.
owenliang
2017-11-24 14:29:52 +08:00
buffered/cached
3dwelcome
2017-11-24 15:53:54 +08:00
free 会归还的。

往大的看,linux 把空余的内存都利用起来了,所以一般是检测 swap 占用率,来确定当前内存的用量。
往小的看,你可以尝试查看 cat /proc/[id]/status,里面有 vmpeak(进程启动后内存的最大占用量)和 vmsize(当前内存占用大小)

或者你技术更好,就用 /proc/[id]/maps 自己算页面大小,看看 malloc 究竟占了你多少空间。

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

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

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

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

© 2021 V2EX