use*_*352 31 c malloc free dynamic-memory-allocation
我在测试程序中观察到以下行为:
我正在malloc()
为1 MB,然后free()
之后sleep(10)
。我做了五次。我正在观察top
程序运行时的内存消耗。
一次free()
-d,我期望程序的虚拟内存(VIRT)消耗将减少1 MB。但实际上并非如此。它保持稳定。这种现象的解释是什么?malloc()
分配内存时是否做一些保留?
Sou*_*osh 42
一次
free()
-d,我期望程序的虚拟内存(VIRT)消耗将减少1MB。
好吧,这不是C标准所保证的。它只是说,一旦您free()
有了内存,就不应该再访问它了。
内存管理器决定是将内存块实际返回到可用内存池,还是留作以后的分配。
Ame*_*een 28
C标准并不强制上的实施者malloc
和free
对内存直接返回给操作系统。因此,不同的C库实现将表现不同。他们中有些人可能会直接将其还给他人,有些则可能不会。实际上,同一实现也将根据分配大小和模式而有所不同。
当然,此行为是有充分理由的:
在大多数情况下,free
如果实现决定保留该内存,则无需为内存负责(假设它是一个好的实现)。迟早将其重新分配或返回给OS。因此,针对内存使用情况的优化应基于malloc
-ed和未free
-d的数量。您必须担心的情况是,您的分配模式/大小开始引起内存碎片,这本身就是一个很大的话题。
但是,如果您使用的是嵌入式系统,则可用的内存量有限,并且您需要更多地控制何时分配内存以及如何释放内存以及如何释放内存,那么您需要直接从OS请求内存页并手动进行管理。
编辑:我没有解释为什么您不负责您释放的内存。原因是,在现代OS上,分配的内存是虚拟的。这意味着,如果您在32位系统或10TB 64位系统上分配512MB,只要您不对该内存进行读写操作,它将不会为其保留任何物理空间。实际上,它只会为您从那个大块而不是整个块中触摸的页面保留物理内存。并且在“一段时间不使用该内存”之后,其内容将被复制到磁盘,并且基础物理内存将用于其他用途。
glg*_*lgl 12
这非常取决于所使用的实际malloc实现。
在Linux下,有一个阈值(MMAP_THRESHOLD
)来确定给定malloc()
请求的内存来自何处。
如果请求的数量小于或等于MMAP_THRESHOLD
,则可以通过从所谓的“空闲列表”中获取请求来满足请求(如果已经存储了任何存储块)free()
。否则,将增加程序的“换行”(即数据段的末尾),并且将通过此过程提供给程序的内存用于请求。
在上free()
,已释放的内存块被添加到空闲列表中。如果数据段的末尾有足够的可用内存,则再次移动折线(上面已提及)以缩小数据段,将多余的内存返回给OS。
如果请求的数量超过MMAP_THRESHOLD
,操作系统将请求一个单独的存储块,并在期间再次返回free()
。
另请参阅https://linux.die.net/man/3/malloc。