内存分配器的“杀手对手”?

时间:2011-03-24 09:07:42

标签: algorithm memory-management

在阅读this question关于Windows内存分配器的看似退化的行为,并记住回到this paper关于构建快速排序实现的最坏情况输入之后,我开始想知道:是否可以构建一个在给定黑盒内存分配器的情况下,即使系统中仍有足够的内存,强制该分配器也会使分配请求失败的程序?也就是说,是否可以采用黑盒内存分配器并强制它失败?

我知道这可以通过以棋盘图案分配和释放内存来强制进行大规模碎片来完成,因此在我看来,理想的解决方案会导致失败时分配的字节数最少而导致失败。对于启发了这一点的原始帖子,如果内存分配器有内部错误,理论上可能会导致分配零字节的失败。

关于如何做到这一点的任何想法/想法?

1 个答案:

答案 0 :(得分:2)

取决于“足够的可用内存”的含义。对于一个简单的碎片“攻击”:

  • 进行一次small次分配,直到一次失败[*]。

  • 现在,按地址[**]的顺序对它们进行排序。

  • 免费提供100次备用分配。

  • 尝试分配100*small个字节。

分配器很可能无法找到连续的内存来满足这一要求。如果它具有small页面大小,并且与物理内存相比有足够的虚拟地址空间,那么它可能能够重新安排操作 - 但这需要MMU的功能在任何反碎片策略之上由分配者。

如果“足够的可用内存”意味着large内存块以前是一个连续的块,则会被分成几个分配,所有这些分配都已被释放,现在分配器将其视为单独的块,因此无法分配large字节然后没有,我不认为你可以强制任意块框分配器无法合并块。某些分配器或其他分配器可能比Windows在其他问题中做的工作要多得多,以保证相邻的空闲块始终合并。

[*]可能的问题 - 过度提交的内存分配器可能不会失败,您只是遇到段错误或您的进程被终止。在这样的系统上,您可能需要跟踪可用的内存量。

[**]可能的问题 - 在C和C ++中,operator<无法保证正常工作。但在几乎所有系统上都是这样,而在C ++中也有std::less