内存池的初始块大小
Initial block size for memory pool
我正在使用C++模板实现一个内存池类,我想知道块的大小应该是多少。例如:
template <typename T>
class Mempool {
unsigned char* block;
// constructor.
Mempool() {
block = malloc(sizeof(T)*DEFAULT_N)
}
};
在上面的例子中,块大小实际上取决于类型T
和要创建的元素数量的默认值。这样做的最佳(或常见)做法是什么?我应该在这里考虑块大小的内存对齐吗?
我只能给出一些一般性的建议,因为这在很大程度上取决于实际用例:
对齐:我想这个池应该确保其中的对象正确对齐。这意味着您可能希望将对象放置在至少是std::alignment_of<T>::value
或alignof(T)
的倍数的内存位置。
缓存友好性:池还可以将对象位置四舍五入到缓存行大小的倍数,因此(小)对象永远不会跨两个缓存行放置,而是始终位于一个缓存行中。
填充:如果对象很小(只有几个字节),但你有很多对象,那么任何额外的填充都可能会大大增加内存需求,这取决于应用程序是否会出现问题。当对象没有放在紧密的位置并且有很多缓存未命中时,过多的填充实际上可能会影响性能。
底层内存管理:最后,良好的块大小也可能取决于底层存储。您可能希望您的分配大小与操作系统页面大小相匹配,或者使用它们的倍数。此外,如果malloc
代价高昂,那么您可能希望尽可能少地调用它,以避免系统调用开销和争用。在malloc
更便宜的环境中,可以更频繁地使用较小的初始块大小和malloc
,尽管malloc
仍将有一些开销。其中很大一部分是特定于操作系统的。
因此,无论您选择什么初始大小,都应该衡量一些典型工作负载的内存使用率和分配性能。这将使你能够做出比纯粹猜测更具教育意义的估计。
最后,还有现成的malloc替换,如tcmalloc、jemalloc,它们可能具有与操作系统的malloc
完全不同的特性。因此,一个好的选择是检查其中一个,而不是滚动自己的分配器。
- 将字符串存储在c++中的稳定内存中
- C++ 指针的内存地址和指向数组的内存地址如何相同?
- Win32编译器选项和内存分配
- 当vector是tje全局变量时,c++中vector的内存管理
- 带内存和隔离功能的SQLite
- 是否可以通过C++扩展强制多个python进程共享同一内存
- 迭代时从向量和内存中删除对象
- 在C++中打印指向不同基元数据类型的指针的内存地址
- 这个指针和内存代码打印是什么?我不知道是打印垃圾还是如何打印我需要的值
- 多个文件的内存分配错误"在抛出 'std :: bad_alloc' what (): std :: bad_alloc 的实例后终止调用" [C++]
- 为什么示例代码访问IUnknown中已删除的内存
- 如何在C++类内存结构中创建"spacer"?
- 从构造函数抛出异常时如何克服内存泄漏
- malloc() 可能出现内存泄漏
- 如何理解将半精度指针转换为无符号长指针和相关的内存对齐
- 在调用FreeLibrary后,释放动态链接到具有相同版本的CRT堆的DLL的内存
- 如何针对特定情况调试和修复此双自由内存损坏问题
- 类型总是使用其大小存储在内存中吗
- 有没有一种方法可以测量c++程序的运行时内存使用情况
- 有没有一种方法可以使用placement new将堆叠对象分配给分配的内存