首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >malloc实现会将释放的内存返回给系统吗?

malloc实现会将释放的内存返回给系统吗?
EN

Stack Overflow用户
提问于 2010-02-07 07:58:12
回答 8查看 20.7K关注 0票数 63

我有一个使用频繁内存分配-释放的长寿命应用程序。是否会有任何malloc实现将释放的内存返回给系统?

在这方面,什么是行为:

google threaded malloc)

  • solaris 10-11 default malloc和mtmalloc

  • FreeBSD 8 default malloc (jemalloc)

  • Hoard malloc?

  • ptmalloc 1、2(默认为glibc)或3

  • dlmalloc

  • tcmalloc (threaded
  • 10-11 default malloc和glibc 8 default malloc(jemalloc)
  • Hoard malloc?)

更新

如果我有一个应用程序,它的内存消耗在白天和晚上可能有很大的不同(例如),我可以强制任何malloc将释放的内存返回给系统吗?

如果没有这样的返回,释放的内存将被多次换出和换入,但这样的内存只包含垃圾。

EN

回答 8

Stack Overflow用户

回答已采纳

发布于 2010-10-05 10:35:58

以下分析仅适用于glibc (基于ptmalloc2算法)。有一些选项似乎对将释放的内存返回系统很有帮助:

  1. mallopt() (在malloc.h中定义)提供了使用参数选项M_TRIM_THRESHOLD之一设置修剪阈值的选项,这表示数据段顶部允许的最小可用内存量(以字节为单位)。如果内存数量低于这个阈值,则glibc会调用brk()将内存回馈给内核。

在Linux中,M_TRIM_THRESHOLD的默认值被设置为128K,设置一个较小的值可能会节省空间。

可以通过在环境变量MALLOC_TRIM_THRESHOLD_中设置修剪阈值来实现相同的行为,而完全不需要更改源代码。

然而,使用M_TRIM_THRESHOLD运行的初步测试程序表明,即使malloc分配的内存确实返回到系统,最初通过brk()请求的实际内存块(竞技场)的剩余部分往往会被保留。

  1. 可以通过调用malloc_trim(pad) (在malloc.h中定义)来裁剪内存区域并将任何未使用的内存返回给系统。此函数调整数据段的大小,在其末尾保留至少pad个字节,如果可释放的字节少于一页,则会失败。段大小始终是一页的倍数,在i386上为4,096字节。

使用malloc_trim实现这种修改后的free()行为可以使用malloc钩子功能来完成。这将不需要对核心glibc库进行任何源代码更改。

glibc.中使用

  1. madvise()系统调用的免费实现
票数 39
EN

Stack Overflow用户

发布于 2010-02-07 08:26:20

大多数实现都不会去识别那些(相对少见的)整个“块”(无论大小适合操作系统)已被释放并可以返回的情况,但当然也有例外。例如,我引用了the wikipedia page在OpenBSD中的话:

在调用free时,使用munmap释放内存并从进程地址空间取消映射。该系统旨在通过利用OpenBSD的mmap系统调用中实现的地址空间布局随机化和gap页功能来提高安全性,并检测释放后使用的错误-由于大量内存分配在释放后完全未映射,进一步使用会导致分段错误和程序终止。

不过,大多数系统并不像OpenBSD那样以安全为中心。

知道这一点,当我编写一个长时间运行的系统,它有一个已知的对大量内存的暂时需求时,我总是尝试fork进程:然后父进程只是等待来自子进程的结果(通常在管道上),子进程进行计算(包括内存分配),返回结果(在所述管道上),然后终止。这样,我的长时间运行的进程将不会在其内存需求的偶尔“峰值”之间的较长时间内无用地占用内存。其他替代策略包括针对此类特殊需求切换到自定义内存分配器(C++使其变得相当简单,尽管底层是虚拟机的语言通常不会)。

票数 17
EN

Stack Overflow用户

发布于 2013-12-16 02:45:00

我在我的应用程序中遇到了类似的问题,经过一些调查后,我注意到,由于某种原因,当分配的对象很小(在我的例子中小于120字节)时,glibc不会向系统返回内存。

看看这段代码:

#include <list>
#include <malloc.h>

template<size_t s> class x{char x[s];};

int main(int argc,char** argv){
    typedef x<100> X;

    std::list<X> lx;
    for(size_t i = 0; i < 500000;++i){
        lx.push_back(X());
    }

    lx.clear();
    malloc_stats();

    return 0;
}

程序输出:

Arena 0:
system bytes     =   64069632
in use bytes     =          0
Total (incl. mmap):
system bytes     =   64069632
in use bytes     =          0
max mmap regions =          0
max mmap bytes   =          0

大约64 MB未返回系统。当我将类型定义更改为:typedef x<110> X;时,程序输出如下所示:

Arena 0:
system bytes     =     135168
in use bytes     =          0
Total (incl. mmap):
system bytes     =     135168
in use bytes     =          0
max mmap regions =          0
max mmap bytes   =          0

几乎所有的内存都被释放了。我还注意到,在这两种情况下使用malloc_trim(0)都会将内存释放给系统。

以下是将malloc_trim添加到上面的代码后的输出:

Arena 0:
system bytes     =       4096
in use bytes     =          0
Total (incl. mmap):
system bytes     =       4096
in use bytes     =          0
max mmap regions =          0
max mmap bytes   =          0
票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/2215259

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档