技术解析

free 内存的时候,内存是否会还给 OS 重新分配?
0
2021-06-28 06:51:21
idczone

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


取决于 glibc 或者是其他 malloc 提供者的实现

一般是 glibc 会复用 free 的内存,以尽量减少内存碎片的产生。。如果 free 一点就还给 os 一点内存很快就没法用了

malloc 这种分配器实现应该会维护一个分配链表,free 之后会将内存重新置为可分配状态,应该不会还给 OS,我觉得

现有用户态 malloc 实现通常会向 kernel 申请一段内存自己优化管理,释放后会带来空隙,也就是碎片化
当然空隙以后被填上,开销比每次申请小很多

不应该永远不还 很可能不立即还

这个描述最简洁。

一般不会,这样做效率太低

我记得当年我还就这个问题写过一篇博客...下面这个是我当时搜到的资料,你可以看看.
https://www.ibm.com/developerworks/linux/library/l-memory/

看到这个问题,立马取找出源码看了有一会了,glibc\malloc\malloc.c,里面有引用 arena.h,恰好之前也在 cii 中看到过 arena 得实现,好像是有维护一个已释放的内存链表,好像这是为了避免在相同进程中使用同一内存地址,细看还得花时间^o^

64*1024 个字节呢,不少吧

没有新的连接建立的时候,内存也一直都没有释放,一直都不变

也就是说内存已经释放了,但是 OS 不会再一次分配给这个进程?

方便贴出来博客的连接吗?一大段英文 get 不到重点

linux 平台的实现应该都是一样的吧

看看这两篇:
http://blog.csdn.net/maokelong95/article/details/52006379
https://www.zhihu.com/question/25527491

好像我说的记得有点问题,应该 arena 就是内存池,会返回重复得内存地址,我测试
int *a = (double *)malloc(sizeof(double));
free(a);
int *b = (double *)malloc(sizeof(double));
free(b);
在 ubuntu16.4 64 位下测试结果 a 和 b 指向相同地址

复制错了,sizeof(int); 你可以测试一下


额,不好意思啊,我博客太多隐私的东西了.
简单来说就是不立刻还给系统,malloc 会自己保存一个很大的串来进行管理.
有专门的函数控制这个,你可以搜索一下.

buffered/cached

free 会归还的。
往大的看,linux 把空余的内存都利用起来了,所以一般是检测 swap 占用率,来确定当前内存的用量。
往小的看,你可以尝试查看 cat /proc/[id]/status,里面有 vmpeak(进程启动后内存的最大占用量)和 vmsize(当前内存占用大小)
或者你技术更好,就用 /proc/[id]/maps 自己算页面大小,看看 malloc 究竟占了你多少空间。

关于 top 里 virt 和 res 区别,想说几句。理解这个才能更好的测试数据。
前者是分配的内存,也就是 new/malloc 了多少,比如说 malloc 了 500M,那 virt 就是 500M.
后者是分配后,你实际使用的内存。比如 malloc 了 500M,但你代码里,只访问的前 50M 数据,那操作系统会很聪明的,只在物理内存里划分 50M 给你,剩下的就不占物理内存了,因为这部分你暂时没用到啊。所以 res 是 50M。
如果是有内存回收机制的,看 vmpeak/vmsize 也许不行,但纯 C++写的代码,是可以这样看的。

多谢指导,再问一下,我启动程序的时候 top 看内存的时候 VIRT 直接到了 1523M,但是 RES 只有 15M,%MEM 也只有%0.8,这是什么原因?


/proc/[id]/status 文件里面显示的是
VmPeak: 1559568 kB
VmSize: 1559568 kB

当年在 ddwrt 只有 ralink 的设备通过 echo drop_cache 使这个 32M 内存的 dlink600 具备无限回复内存的能力。而同样版本针对 tplink wa701 的只会越用越少,所以针对这种设备直接每天定时重启,因为过低的内存至少已知会导致 dnsmasq 崩溃。

madvise()

这种问题,还是不要探究的好。
计算机专业的操作系统专业书可以看看了解下原理,至于你真的要完全搞明白 Linux 和其他 OS 是怎样管理内存的,没这必要,也不是普通人随随便便就能搞明白的。就算搞明白了对你也没什么用。
你只要知道操作系统自己会「智能」管理内存就行了。如果你自己开发程序,特别是 c、c++之类的,特别注意不要 leak 内存就 ok.
如果是 linux 系统管理,把重点放在观察 ps 命令里面那个 rss。

数据地带为您的网站提供全球顶级IDC资源
在线咨询
专属客服