3 回答
TA贡献1772条经验 获得超8个赞
假设您有一个“大”(32个字节)的空闲内存:
----------------------------------
| |
----------------------------------
现在,分配其中的一些(5次分配):
----------------------------------
|aaaabbccccccddeeee |
----------------------------------
现在,释放前四个拨款,但不释放第五个拨款:
----------------------------------
| eeee |
----------------------------------
现在,尝试分配16个字节。哦,我做不到,尽管有两倍的免费。
在具有虚拟内存的系统上,碎片问题不像您想象的那么严重,因为大型分配只需要在虚拟地址空间,不在物理地址空间。所以在我的例子中,如果我有一个页大小为2字节的虚拟内存,那么我就可以使我的16字节分配没有问题。物理内存如下所示:
----------------------------------
|ffffffffffffffeeeeff |
----------------------------------
而虚拟内存(大得多)可能如下所示:
------------------------------------------------------...
| eeeeffffffffffffffff
------------------------------------------------------...
内存碎片的典型症状是,您试图分配一个大块,但无法分配,即使您似乎有足够的内存空闲。另一个可能的后果是进程无法将内存释放回操作系统(因为在它从操作系统分配的所有块中仍然有一些对象在使用,尽管这些块现在大部分是未使用的)。
防止C+中内存碎片的策略是根据对象的大小和/或预期寿命分配来自不同区域的对象。所以,如果你要创建大量的对象,然后一起销毁它们,那么就从一个内存池中分配它们。您在它们之间执行的任何其他分配都不会来自池,因此不会位于它们之间的内存中,因此内存不会因此而被分割。
一般情况下,您不需要担心它,除非您的程序是长期运行,并做了大量的分配和释放。当你将短命和长寿的物体混合在一起时,你面临的风险最大,但即便如此,也是如此。malloc会尽全力帮助你。基本上,忽略它直到您的程序有分配失败或意外导致系统在内存上运行不足(在测试中捕捉到这一点,用于首选!)。
标准库并不比任何分配内存的库更糟糕,标准容器都有一个Alloc模板参数,您可以使用它来微调它们的分配策略(如果绝对必要的话)。
- 3 回答
- 0 关注
- 1418 浏览
添加回答
举报