[英]Is STL memory management “reliable” for a long running program?
我在C ++ 11 STL中阅读了很多关于内存管理的帖子,但我找不到令人满意的答案。
我的情况:我开发了一个长期运行的服务器[它运行大约4-6周]。 目前我使用了很多位于堆栈上的旧 C代码char [x][y]
或char [z]
变量。
我怀疑 STL内存管理是否仍然可靠 ,在一个运行数周的程序中广泛使用它,并在此期间服务超过1000万个线程,每个线程将有很多STL操作。
更具体一点:我想将位于堆栈上的所有修复大小的变量重写为std::vector<std::string>
或std::string
类型。
我的问题:
编译器是gcc 4.9.3
我可以完全安全地将我的程序重写为新的现代STL表示法并摆脱旧的C代码吗?
首先,STL不是新的; 它可以追溯到C ++本身标准化之前。 其次,我们称之为C ++标准库。
第三,只要你的线程遵循C ++的要求(即:不以C ++不允许的方式终止),并且你不泄漏内存,那么是的,你会没事的。
在数百万个线程中长时间运行时是否存在任何内存碎片?
你将从生活在堆栈上的对象转向动态分配内存。 当然存在内存碎片化的可能性。
这与C ++标准库容器完全无关。 这是使用动态分配的产物。
同样重要的是,如果要使用更好的固定大小的堆栈数组,可以使用std::array<char, ...>
。 然后,在很多情况下,使用小字符串优化的std::string
实现提供了相当好的折衷,如果字符串低于某个最大大小,则放弃分配内存。
性能如何? 使用堆栈上具有变量的旧C代码不会对性能产生任何影响。
它使你的堆栈更长,这给了1000万个线程,可能会导致你提交更多页面的内存。 然后,也许不是。
无论如何,当涉及到超线程应用程序时,内存分配总是一个问题。 内存分配本质上必须是可重入的。 这意味着互斥锁定等等。
您可以设计分配和释放内存的原子方法,但这往往需要分配固定大小。 而这些事情往往有其自身的缺点。 您可以拥有从中分配的线程本地内存池。 所有这些都需要使用自己的内存分配器。
但最重要的是......这些问题再次无关使用C ++标准库类型具体 。 这就是从静态内存到动态分配时会发生的情况。 无论您使用的是malloc/free
还是标准库容器,问题都在于动态分配。
首先,我非常感谢所有评论和Nicol的回答。 关于碎片化的他的最后一条评论在头上打了一针。
1)破碎取决于正是这些数以百万计的线程正在做的事情的细节。
在深入分析了项目后,我意识到有数百万个内存分配和发布。
因此我编写了自己的STL Memory Allocator:
unordered_map
来维护所有指针。 我的STL内存分配器记录所有请求,这是摘要[摘要]:
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字节的维护数据。 Eq分配1个字节导致实际48字节大小的存储器块。 Max Used Pointers
:这是所有正在运行的线程同时使用此大小的内存块的数量。 换句话说,该存储器[ Size * Max Used Pointers
]是从OS物理分配的。 Total Requested Count
:每次Total Requested Count
[对齐大小]分配时,此计数都会增加。 对我来说,这意味着我可以保存数百万的分配和发布,我不知道碎片在默认的STL分配器上会是什么样子。
2)我可以摆脱旧的C风格代码,我可以使用更方便的STL容器。
3)表现还可以 。 对我而言,这意味着我的分配器不是最快的,但考虑到它完全是多线程安全的,并且每秒服务数千个请求,它完全满足我的需求。
所以,答案是,[公平]我仍然不知道默认的STL内存分配器有多可靠,但由于我所提到的事实 - 至少 - 一个线索内部发生的事情。
假设我的分配器没有错误[我可以期待长时间运行并提供数百万个请求]我可以为我关闭此案例。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.