[glibc] free之后的内存什么时候还给操作系统?

最近遇到一个关于程序释放(free函数调用后的)的内存什么时候返回给操作系统的问题。这里以glibc为例,每一种内存管理程序的实现可能都不一样。整体思路大体都是按照不着急还回去,以备将来的不时之需!

从glibc的内部看,返回给系统的途径,要根据申请的方式来判断,比如根据实现,使用sbrk/brk申请的内存,要用sbrk/brk来返回给操作系统。如果是使用mmap申请的内存,调用的系统函数就是munmap。这些从用户角度来看是看透明的,要看具体的malloc接口文档,里面有关于选用方式的说明。我们可以根据glibc提供的一些参数,环境变量的设置来看具体使用哪一个方式。详细的说明要看这个里面的说明(而且可以使用mallopt接口更改某些参数值):
https://www.man7.org/linux/man-pages/man3/mallopt.3.html

从调用方式上看,程序可以主动返还内存的方法是:malloc_trim。另一个方法是,让glibc自动返还内存的方法,如果是sbrk的话,是根据参数设置:
FASTBIN_CONSOLIDATION_THRESHOLD:这个是宏定义改不了,值是64K;意思是说,当释放的内存(和前后可以整合的chunk之和)大小超过了这个值,就会走入整合的逻辑,在整合之后根据heap里的top空闲内存的大小(和M_TRIM_THRESHOLD作比较)来判断释放要做trim。

M_TRIM_THRESHOLD,这个是默认128K(所以上面那个值是64K,是这个值的一半)。如果空虚内存大于这个值,就做trim。

如果是mmap申请的内存,不受这两个参数限制,如果是free不用了,总是会被返回给操作系统。

所以需要根据自己的具体情况来看,要看返还所带来的效益高低:比如系统的总内存不够用,就需要程序主动返还;如果系统内存够用,返还回去,程序后续还得再次申请,就不如不返还。

最后,目前看是没有办法来看,到底free了多少,同时又没有返还给操作系统。需要自己单独写工具来看。比较麻烦。但也不是不可能!另一个问题,那这一部分释放的内存,会在系统需要的时候由系统回收呢?其实没有这样的逻辑。如果系统内存不够用,可能会导致新的程序例的内存申请返回errno=12,申请不到内存。即使之前的程序已经调用了free函数,但是仍然没有返回给系统。

https://www.gnu.org/software/libc/manual/html_node/Freeing-after-Malloc.html

Occasionally,free can actually return memory to the operating system and make the process smaller. Usually, all it can do is allow a later call to malloc to reuse the space. In the meantime, the space remains in your program as part of a free-list used internally by malloc.这个文档里也说是有可能。

举例:假如一个程序,申请的都是小内存,连续申请2G。后续即使使用free函数释放了这2G的内存,但是依然会保留在程序的“常驻内存区”。

如果free之后,调用了malloc_trim:就可以释放这2G的内存。或者后续有大于32K(要看具体的设置)大小内存整体free的操作,也是有机会调用到trim的操作。

猜你喜欢

转载自blog.csdn.net/qq_36428903/article/details/134887326