堆栈展开后,Linux堆栈驻留内存未回收

时间:2013-01-17 22:45:45

标签: linux unix memory-management linux-kernel mmap

如果在堆栈上分配,Linux不再使用内存,则不会回收内存。

我在堆上动态分配(malloc / mmap)1GB。

  • 分配前:
  

$ top

     

虚拟内存1GB

     

驻留记忆〜0

  • memset 1GB
  

$ top

     

虚拟内存1GB

     

常驻内存1GB

  • 取消分配(免费/ munmap)1GB - 按预期收回
  

$ top

     

虚拟内存1GB

     

驻留记忆〜0

堆栈

我在堆栈上动态分配1GB。

  • 之前:
  

$ top

     

虚拟内存1GB

     

驻留记忆〜0

  • memset 1GB
  

$ top

     

虚拟内存1GB

     

常驻内存1GB

  • 解除分配(堆栈展开)1GB - 驻留内存仍然是1GB,即使在解除分配后!为什么?
  

$ top

     

虚拟内存1GB

     

常驻内存1GB

为什么,当堆栈展开常驻内存(物理页面仍在使用中)?

使用mmap完成堆段分配,并使用mmap完成堆栈段分配 - 那么为什么reclaim的行为存在差异?

1 个答案:

答案 0 :(得分:3)

因为操作系统认为一旦你使用了那么多堆栈,你可能会再次这样做。操作系统无法真正了解[来自您的应用程序之外]您的应用程序将来要做什么。很难弄清楚什么时候可以释放一些堆栈,并且你在操作系统中得到各种有趣的竞争条件,你必须停止应用程序运行只是为了减少它的堆栈 - 然后它突然需要它,所以它需要分配。

另一方面,使用mmap,有一个明确的munmap告诉操作系统“我对这个记忆没兴趣”。因此它被释放然后[作为munmap调用本身的一部分 - 特别是在zap_pte_range中,页面本身被释放并返回给操作系统。

除非满足以下条件,否则它不应该是一个大问题:  1.您正在没有交换的嵌入式系统上运行。  2.你的应用程序在返回使用大量堆栈后运行了很长一段时间(假设你确实需要这么多的内存作为堆栈,你需要在需要时提供这些内存,所以它显然只是一个如果应用程序稍后不需要堆栈并且该时间段很长 - 无论您对long的定义是什么,都会出现问题。  3.您的系统没有足够的RAM来满足其他应用程序中的其他RAM需求。

我说的原因是虽然堆栈使用了那么多内存,但如果应用程序长时间不使用ram,并且系统内存不足,则会将其交换到磁盘 - 如果需要,可以在稍后阶段进行交换。

我还会说使用如此大量的堆栈空间通常被认为是个坏主意。堆栈上的空间不足[达到限制或“只有可用的内存不足”]几乎总是致命的。

因此,虽然我经常建议使用堆栈空间来存储临时变量,但我认为1GB的堆栈是非常过分的。几兆字节应该是可以接受的,但是数百兆字节或更多可能是“你应该以另一种方式存储东西”的标志。