C/C++ 分块内存分配

C/C++ memory allocation chunkwise

鉴于以下情况,关于 space/time 消费最合适的、平台无关的方法是什么:

(1) 在给定时间点,一组对象的总大小为 已知。因此,所需的内存可以在一个节拍中分配。

(2) 内存所有权需要分配给每个单独的对象 释放(解除分配)的时间未定。

我的临时方法是某种类型的引用计数 分配的内存块。任何时候对象被释放引用 计数减少。当它为零时,大块被释放。

有没有更合适的模式或惯例?

给定的情况不足以确定 "best" 方法。

(1) At a given point in time the total size of a set of objects is known. Thus, the required memory could be allocated in one beat.

如果所有分配都发生在程序的初始部分,那么这个事实对我们没有帮助(除非加快启动时间至关重要)。如果程序频繁销毁和创建新对象,这也无济于事,因为内存分配器无论如何都不会将其堆内存释放回 OS;它只是为了将来 自己 使用而发布它。

此信息有用的唯一情况是程序生命周期内发生的所有对象分配和释放都是同一对象类型。在这种情况下,内存池实现将提高性能,因为找到下一个可用的分配槽总是 O(1)。 例如,这是一个 implamanment (source).

如果你还知道每种对象类型的对象总大小,那么多个内存池也会非常有用。如果不是这种情况,那么您总是可以将所有对象四舍五入到最大对象大小并在浪费内存的情况下提高性能(使用内存池)。

(2) The memory ownership needs to be distributed to each single object and the time of free-ing (deallocation) is undetermined.

处理对象生命周期很困难,最佳方法取决于以下 3 个问题:

  • 单个对象有多少个引用?
  • 这个对象被传递了多少次?
  • 您的对象的图形是否包含循环?

如果这些问题的答案是 "A couple, not much and no",那么 std::shared_ptr<> 可能会很有帮助。然而,如果引用的数量不是那么少,或者对象不断地从一只手转移到另一只手,那么引用计数可能会在每次转移时计算引用时产生大量开销。如果您的对象图中有循环,那么 内存泄漏 发生。 在这种情况下,垃圾收集解决方案很可能具有更好的性能并且更易于管理(请参阅 Boeham 的 C 和 C++ 实现)。

My adhoc approach would be some type of reference counting on the allocated chunk of memory. Any time an object is free-ed the reference count decreases. When its zero the big chunk is freed.

考虑到 free() 并没有真正将内存释放回 OS,我看不到这种方法有任何好处。您只会有更多的管理开销而不会获得任何性能。 您在问题中没有提到需要将内存释放回 OS 所以我想这不是问题。

Is there any pattern or common practice that would be more appropriate?

您可以实现的最重要的改进是不再需要使用内置内存管理,因为它是为通用目的而设计的。它考虑了一切,因此性能相对较差。 例如,管理线程之间的同步。

如果你不使用多个线程并且内存池解决方案适用于你,那么使用它们;他们可能会有最好的表现,而且他们很简单。 如果内存池不适用,and/or 你在你的程序中使用了很多线程,那么我会选择许多替代内存分配器之一。我知道的一个很好的多线程内存分配器是 Hoard.