STL内存管理对于长期运行的程序是"可靠的"吗?

Al *_*ndy 2 c++ memory-management stl c++11

我在C++ 11 STL中阅读了很多关于内存管理的帖子,但我找不到令人满意的答案.

我的情况:我开发了一个长期运行的服务器[它运行大约4-6周].目前我使用了很多旧的 C代码char [x][y]char [z]位于堆栈上的变量.

怀疑 STL内存管理是否仍然可靠,在一个运行数周的程序中广泛使用它,并在此期间服务超过1000万个线程,每个线程将有很多STL操作.

更具体一点:我想重写位于堆栈std::vector<std::string>std::string键入的所有修复大小的变量.

我的问题:

  1. 我可以完全安全地将我的程序重写为新的现代STL表示法并摆脱旧的C代码吗?
  2. 在数百万个线程中长时间运行时是否存在任何内存碎片
  3. 性能如何?使用堆栈上具有变量的旧C代码不会对性能产生任何影响.

编译器是 gcc 4.9.3

Nic*_*las 15

我可以完全安全地将我的程序重写为新的现代STL表示法并摆脱旧的C代码吗?

首先,STL不是新的; 它可以追溯到C++本身标准化之前.其次,我们称之为C++标准库.

第三,只要你的线程遵循C++的要求(即:不以C++不允许的方式终止),并且你不泄漏内存,那么是的,你会没事的.

在数百万个线程中长时间运行时是否存在任何内存碎片?

你将从生活在堆栈上的对象转向动态分配内存.当然存在内存碎片化的可能性.

这与C++标准库容器完全无关.这是使用动态分配的产物.

同样重要的是,std::array<char, ...>如果您想使用更好的固定大小的堆栈数组,您可以使用它.然后,std::string在很多情况下,使用小字符串优化的实现提供了相当好的折衷,如果字符串低于某个最大大小,则放弃分配内存.

性能如何?使用堆栈上具有变量的旧C代码不会对性能产生任何影响.

它使你的堆栈更长,这给了1000万个线程,可能会导致你提交更多页面的内存.然后,也许不是.

无论如何,当涉及到超线程应用程序时,内存分配总是一个问题.内存分配本质上必须是可重入的.这意味着互斥锁定等等.

您可以设计分配和释放内存的原子方法,但这往往需要分配固定大小.而这些事情往往有其自身的缺点.您可以拥有从中分配的线程本地内存池.所有这些都需要使用自己的内存分配器.

但最重要的是......这些问题再次无关使用C++标准库类型具体.这就是从静态内存到动态分配时会发生的情况.无论您是使用malloc/free标准库容器还是标准库容器,问题都在于动态分配.

  • 关于C堆栈_bigger_的好点.随着现在GCC支持[小字符串优化](http://stackoverflow.com/questions/31228579/why-is-cow-stdstring-optimization-still-enabled-in-gcc-5-1),你甚至会得到两全其美:堆栈短字符串(无碎片问题),对堆长字符串(不断叠加小).除非你自己动手,否则还没有4.9.3. (2认同)
  • @einpoklum:"*OP询问他是否可以确定碎片不会随着时间的推移逐渐增加,直到他的内存耗尽.*"碎片不会导致内存不足.它只会导致您无法找到足够的连续空闲内存.此外,有没有办法知道,因为它依赖于准确**这些数以百万计的线程正在做的事情的细节.所以问题的一部分实际上是无法回答的. (2认同)