为了账号安全,请及时绑定邮箱和手机立即绑定

什么是内存碎片?

什么是内存碎片?

C++
慕无忌1623718 2019-07-13 18:52:51
我听说过在C+动态内存分配上下文中使用过几次“内存碎片”一词。我发现了一些关于如何处理内存碎片的问题,但是找不到一个直接的问题来处理它本身。因此:什么是内存碎片?如何判断内存碎片是否是应用程序的问题?什么样的节目最有可能受到影响?处理内存碎片的好方法是什么?此外:我听说过大量使用动态分配可以增加内存碎片。这是真的吗?在C+的上下文中,我理解所有标准容器(std:string、std:Vector等)都使用动态内存分配。如果这些内容在整个程序(特别是std:string)中使用,那么内存碎片更有可能是一个问题吗?如何在STL密集型应用程序中处理内存碎片?
查看完整描述

3 回答

?
料青山看我应如是

TA贡献1772条经验 获得超8个赞


假设您有一个“大”(32个字节)的空闲内存:


----------------------------------

|                                |

----------------------------------

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


----------------------------------

|aaaabbccccccddeeee              |

----------------------------------

现在,释放前四个拨款,但不释放第五个拨款:


----------------------------------

|              eeee              |

----------------------------------

现在,尝试分配16个字节。哦,我做不到,尽管有两倍的免费。


在具有虚拟内存的系统上,碎片问题不像您想象的那么严重,因为大型分配只需要在虚拟地址空间,不在物理地址空间。所以在我的例子中,如果我有一个页大小为2字节的虚拟内存,那么我就可以使我的16字节分配没有问题。物理内存如下所示:


----------------------------------

|ffffffffffffffeeeeff            |

----------------------------------

而虚拟内存(大得多)可能如下所示:


------------------------------------------------------...

|              eeeeffffffffffffffff                   

------------------------------------------------------...

内存碎片的典型症状是,您试图分配一个大块,但无法分配,即使您似乎有足够的内存空闲。另一个可能的后果是进程无法将内存释放回操作系统(因为在它从操作系统分配的所有块中仍然有一些对象在使用,尽管这些块现在大部分是未使用的)。


防止C+中内存碎片的策略是根据对象的大小和/或预期寿命分配来自不同区域的对象。所以,如果你要创建大量的对象,然后一起销毁它们,那么就从一个内存池中分配它们。您在它们之间执行的任何其他分配都不会来自池,因此不会位于它们之间的内存中,因此内存不会因此而被分割。


一般情况下,您不需要担心它,除非您的程序是长期运行,并做了大量的分配和释放。当你将短命和长寿的物体混合在一起时,你面临的风险最大,但即便如此,也是如此。malloc会尽全力帮助你。基本上,忽略它直到您的程序有分配失败或意外导致系统在内存上运行不足(在测试中捕捉到这一点,用于首选!)。


标准库并不比任何分配内存的库更糟糕,标准容器都有一个Alloc模板参数,您可以使用它来微调它们的分配策略(如果绝对必要的话)。


查看完整回答
反对 回复 2019-07-13
  • 3 回答
  • 0 关注
  • 1418 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信