【发布时间】:2010-11-28 03:13:32
【问题描述】:
这是我的问题:调用 free 或 delete 是否会将内存释放回“系统”。我的意思是系统,它会减少进程的数据段吗?
让我们考虑一下 Linux 上的内存分配器,即 ptmalloc。
据我所知(如果我错了,请纠正我),ptmalloc 维护一个内存块的空闲列表,当内存分配请求到来时,它会尝试从这个空闲列表中分配一个内存块(我知道,分配器比这复杂得多,但我只是用简单的话来说)。但是,如果它失败了,它会使用 say sbrk 或 brk 系统调用从系统中获取内存。当内存被释放时,该块被放置在空闲列表中。
现在考虑这种情况,在峰值负载时,堆上分配了很多对象。现在,当负载减少时,对象就被释放了。所以我的问题是:一旦对象被释放,分配器会做一些计算来确定它是否应该只将这个对象保留在空闲列表中,或者根据空闲列表的当前大小,它可能决定将该内存还给系统即使用sbrk或brk减少进程的数据段?
glibc 的文档告诉我,如果分配请求远大于页面大小,它将使用 mmap 进行分配,并在释放后直接释放回系统。凉爽的。但是假设我从不要求分配大于 50 字节的大小,并且在系统的峰值负载时我要求很多这样的 50 字节对象。然后呢?
据我所知(请纠正我),在进程结束之前,使用 malloc 分配的内存永远不会释放回系统,即如果我释放它,分配器只会将它保留在空闲列表中。但是困扰我的问题是,如果我使用一个工具来查看我的进程的内存使用情况(我在 Linux 上使用 pmap,你们用什么?),它应该总是显示在峰值负载下使用的内存(因为内存永远不会归还给系统,除非使用 mmap 分配)?那就是进程使用的内存永远不会减少(堆栈内存除外)?是吗?
我知道我遗漏了一些东西,所以请对这一切有所了解。
专家,请澄清我对此的概念。我会很感激。我希望我能够解释我的问题。
【问题讨论】:
-
"它完全依赖于实现。"好的,很酷,假设 Linux 实现永远不会将内存返回给系统。那么我可以相信操作系统的页面替换以确保拥有大地址空间不会导致问题吗?
-
另外我想知道 Linux 实现上发生了什么,即 ptmalloc 在上述场景中的行为是什么。
-
这篇文章的要点:我正在考虑为在我的应用程序中经常在堆上分配和释放的固定大小的对象编写我自己的内存池(在通用分配器即 malloc 之上) .因此,这将消除与从 malloc 获取对象相关的内存开销,并且分配和释放将是 O(1)(摊销)。所以我想知道池是否应该将内存归还给通用分配器,即 malloc 与否。我希望你们能明白这篇文章的要点。谢谢大家的回复。我很感谢大家的欢呼:)