malloc在分配内存时是否保留了更多空间?

问题描述 投票:31回答:3

我在我的测试程序中观察到以下行为:

我正在做malloc()为1 MB然后free()它在sleep(10)之后。我这样做了五次。我在程序运行时观察top中的内存消耗。

一旦free()-d,我预计该程序的虚拟内存(VIRT)消耗将减少1 MB。但实际上并非如此。它保持稳定。这种行为有什么解释? malloc()在分配内存时做了一些保留吗?

c malloc free dynamic-memory-allocation
3个回答
42
投票

一旦free()-d,我预计程序的虚拟内存(VIRT)消耗将减少1MB。

嗯,这不是C标准所保证的。它只是说,一旦你了解内存,你就不应该再访问它了。

内存块是否实际返回到可用内存池或保留在一边以供将来分配,由内存管理器决定。


28
投票

C标准不强制free()malloc的实现者直接将内存返回给操作系统。因此,不同的C库实现将表现不同。他们中的一些人可能会直接退回,有些人可能不会。实际上,根据分配大小和模式,相同的实现也会表现不同。

当然,这种行为有充分的理由:

  1. 并非总是可行。操作系统级别的内存分配通常以页面形式完成(一次4KB,4MB或......大小)。如果在释放另一部分之后仍然使用页面的一小部分,那么在该部分也被释放之前,该页面不能被返回到操作系统。
  2. 效率。应用程序很可能会再次请求内存。那么为什么要回到操作系统并在不久之后再次提出要求。 (当然,保留的内存大小可能有限制。)

在大多数情况下,如果实现决定保留它,你不会对free的内存负责(假设它是一个很好的实现)。迟早它将被重新分配或返回操作系统。因此,优化内存使用应该基于你有free-ed的数量,你没有malloc-d。您需要担心的情​​况是,您的分配模式/大小开始导致内存碎片,这本身就是一个非常大的主题。

但是,如果您在嵌入式系统上并且可用内存量有限,并且您需要更多地控制何时/如何分配和释放内存,则需要直接从操作系统请求内存页并手动管理。

编辑:我没有解释为什么你不对你自由的记忆负责。原因是,在现代操作系统中,分配的内存是虚拟的。这意味着如果您在32位系统或10TB的64位系统上分配512MB,只要您不读取或写入该内存,它就不会为其保留任何物理空间。实际上,它只会为您从该大块而不是整个块触摸的页面保留物理内存。在“一段时间不使用该内存”之后,其内容将被复制到磁盘,底层物理内存将用于其他内容。


12
投票

这非常依赖于使用中的实际malloc实现。

在Linux下,有一个阈值(free)来决定给定MMAP_THRESHOLD请求的内存来自何处。

如果请求的数量低于或等于malloc(),则通过从所谓的“空闲列表”中获取该请求,如果任何内存块已经是MMAP_THRESHOLDd,则满足该请求。否则,程序的free()(即数据段的结尾)增加,并且通过该过程使程序可用的存储器用于请求。

"break line"上,释放的内存块被添加到空闲列表中。如果在数据段的最末端有足够的可用内存,则再次移动中断线(上面提到)以缩小数据段,将多余的内存返回到OS。

如果请求的数量超过free(),则OS会请求单独的内存块,并在MMAP_THRESHOLD期间再次返回。

有关详细信息,请参阅free()

© www.soinside.com 2019 - 2024. All rights reserved.