首先,我同意其他建议资源泄漏的海报。你真的想先排除它。
希望您当前使用的堆管理器能够转储堆中的实际可用总空闲空间(跨所有空闲块)以及它被划分的块总数。如果平均空闲块大小与堆中的总空闲空间相比相对较小,那么您确实存在碎片问题。或者,如果您可以转储最大空闲块的大小并将其与总空闲空间进行比较,那将完成同样的事情。如果您遇到碎片,最大的空闲块相对于所有块中可用的总可用空间将很小。
要非常清楚上述内容,在所有情况下,我们都在谈论堆中的空闲块,而不是堆中分配的块。无论如何,如果不满足上述条件,那么您确实存在某种泄漏情况。
因此,一旦您排除了泄漏,您可以考虑使用更好的分配器。问题中建议的Doug Lea 的 malloc对于一般用途的应用程序来说是一个非常好的分配器,并且在大多数情况下非常健壮。换句话说,它已经过时间测试,可以很好地适用于大多数应用程序。然而,没有一种算法适用于所有应用程序,任何管理算法方法都可能被与其设计相反的正确病理条件破坏。
为什么你有碎片问题?- 碎片问题的来源是由应用程序的行为引起的,并且与同一内存区域中的分配生命周期大不相同。也就是说,一些对象会定期分配和释放,而其他类型的对象会在同一个堆中持续较长时间......将较长生命周期的对象视为在竞技场的更大区域中戳洞,从而防止合并已释放的相邻块。
要解决此类问题,您可以做的最好的事情是在逻辑上将堆划分为生命周期更相似的子区域。实际上,您需要一个临时堆和一个或多个持久堆,它们将具有相似生命周期的事物组合在一起。
其他一些人提出了另一种解决问题的方法,即尝试使分配大小更相似或相同,但这不太理想,因为它创建了一种称为内部碎片的不同类型的碎片 - 这实际上是浪费的空间通过在块中分配比您需要的更多的内存。
此外,使用像 Doug Lea 这样的好的堆分配器,使块大小更相似是不必要的,因为分配器已经在执行两倍大小的分桶方案,这将完全没有必要人为地调整传递给 malloc( ) - 实际上,他的堆管理器会自动为您执行此操作,比应用程序能够进行的调整要强大得多。