什么是内存碎片


想象一下,您拥有“大”(32字节)的空闲内存空间:

---------------------------------- | | ----------------------------------

现在,分配其中一些(5个分配):

---------------------------------- |aaaabbccccccddeeee | ----------------------------------

现在,释放前四个分配,但不释放第五个分配:

---------------------------------- | eeee | ----------------------------------

现在,尝试分配16个字节。糟糕,即使有那么多的免费,我也无法做到。

在具有虚拟内存的系统上,碎片化的问题比您想象的要少,因为大型分配只需要在虚拟地址空间中是连续的,而不需要在物理地址空间中是连续的因此,在我的示例中,如果我的虚拟内存的页面大小为2字节,那么我可以毫无问题地进行16字节分配。物理内存如下所示:

---------------------------------- |ffffffffffffffeeeeff | ----------------------------------

而虚拟内存(更大)可能看起来像这样:

------------------------------------------------------... | eeeeffffffffffffffff ------------------------------------------------------...

内存碎片的经典症状是,即使您似乎有足够的可用内存,您也尝试分配一个大块而您却无法分配。另一个可能的结果是该进程无法将内存释放回OS(因为从OS分配的所有块中仍然有一些对象在使用中,即使这些块现在几乎未使用)。

防止C ++中内存碎片的策略是根据对象的大小和/或预期寿命从不同区域分配对象来进行工作的。因此,如果要创建很多对象并在以后将它们全部销毁,请从内存池中分配它们。您在它们之间进行的任何其他分配都不会来自池,因此不会在内存中位于它们之间,因此不会导致内存碎片。

通常,除非您的程序可以长时间运行并且需要大量分配和释放,否则您不必为此担心。在这种情况下,您面临的风险最大的是短寿命和长寿命的混合物,但即使malloc那样,它也会尽最大努力提供帮助。基本上,请忽略它,直到您的程序出现分配失败或意外导致系统内存不足(优先选择在测试中捕获!)。

标准库不比分配内存的任何其他库差,并且标准容器都有一个Alloc模板参数,如果绝对必要,可以使用它们来微调其分配策略。


免责声明!

本站转载的文章为个人学习借鉴使用,本站对版权不负任何法律责任。如果侵犯了您的隐私权益,请联系本站邮箱yoyou2525@163.com删除。



 
粤ICP备18138465号  © 2018-2025 CODEPRJ.COM