首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >对于一个长期运行的程序来说,STL内存管理“可靠”吗?

对于一个长期运行的程序来说,STL内存管理“可靠”吗?
EN

Stack Overflow用户
提问于 2016-06-15 20:15:14
回答 2查看 773关注 0票数 3

我在C++11 STL中阅读了很多关于内存管理的帖子,但是我并没有找到一个令人满意的答案。

我的情况:我开发了一个长时间运行的服务器,它在4-6周内运行。目前,我使用了大量位于堆栈上的旧C代码char [x][y]char [z]变量。

我怀疑STL内存管理是否仍然可靠,在运行数周的程序中广泛使用它,并在t̲h̲i̲的̲周期中服务于1 000多万个线程,每个线程都有大量的STL操作。

更具体地说:我希望将堆栈中的所有固定大小的变量重写为std::vector<std::string>std::string类型。

我的问题:

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

编译器是gcc 4.9.3

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-07-02 14:05:39

首先,我非常感谢所有的评论和妮可的答复。他最后的评论,关于碎裂,击中了钉子的头。

1)碎片取决于这数百万线程到底在做什么的细节。

在深入分析了这个项目之后,我意识到有数百万内存分配和发布。

因此,我编写了自己的STL内存分配器,其中:

  1. 有一个内部unordered_map来维护所有的指针。
  2. 多线程是安全的。
  3. 根据第1点,它重用被标记为空闲的已释放指针。
  4. 要卸载控制器,通过STL请求的内存大小对齐为16字节大小。

我的STL内存分配器日志所有请求,这是摘要摘要

代码语言:javascript
复制
Statistics:
     Total allocated Memory: 813'041'344 bytes
     Administrative Memory : 3'464'152 bytes
     Available pointers    : 2'500
+-------------------------------------------------------------------------+
| Index | Aligned Memory Size | Max Used Pointers | Total Requested Count |
+-------------------------------------------------------------------------+
|      1|                   48|                296|             49'545'399|
|      2|                   64|                469|             73'226'993|
|      3|                   80|              1'167|             67'108'769|
|      4|                   96|                129|             12'864'168|
|      5|                  112|                281|              4'528'422|
|      6|                  128|                 64|              8'715'454|
|      7|                  144|                 74|              5'148'202|
|     10|                  192|                387|              1'313'920|
|     11|                  208|                 26|              1'311'779|
|     13|                  272|                 56|             11'574'551|
|     15|                  352|                368|              1'178'994|
|     18|                  512|                262|              3'224'044|
|     22|                  656|                  5|              2'586'081|        
+-------------------------------------------------------------------------+

传奇:

  • Aligned Memory Size:每个请求的块对齐16字节+ 32字节的维护数据。E.q.分配1字节将导致一个实际大小为48字节的内存块。
  • Max Used Pointers:这是所有正在运行的线程同时使用这个大小的内存块的数量。换句话说,这个内存Size * Max Used Pointers是从操作系统物理上分配的。
  • Total Requested Count:每次请求分配对齐大小时,此计数都会增加。

对我来说,这意味着我可以节省数百万的分配和发行版,而且我不知道使用默认的STL分配器,碎片会是什么样子。

2)我可以摆脱C风格的旧代码,可以使用更方便的STL容器。

3)演出情况良好。对我来说,这意味着我的分配器不是最快的,但考虑到它完全是多线程安全的,并且每秒处理数千个请求,它完全满足了我的需要。

所以,答案是,平心而论,我仍然不知道默认的STL内存分配器有多可靠,但由于我得到的这些事实--至少是--这是内部情况的一个线索。

假设我的分配器是免费的,在运行了很长一段时间并为数百万个请求提供服务之后,我可以为我关闭这个案例。

票数 1
EN

Stack Overflow用户

发布于 2016-06-15 20:24:53

我能否完全安全地将我的程序重写到新的现代STL表示法,并摆脱旧的C代码?

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

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

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

您将从驻留在堆栈上的对象转到动态分配内存。当然,存在着内存碎片的可能性。

这与C++标准库容器完全无关。这是使用动态分配的结果。

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

那表演呢?使用旧的C代码,在堆栈上设置变量不会对性能产生任何影响。

它使堆栈更长,这给出了1000万个线程,可能会导致您提交更多的内存页。再说一次,也许不是。

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

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

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

票数 16
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37844940

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档