std :: string内存管理
|
我在使用std :: string进行内存管理时遇到问题。
我有应用程序-具有分离线程的多线程服务器(我确实需要加入它们,它们将完成工作并退出),我发现一段时间后内存使用率很高。我已经开始试验问题出在哪里,并且已经创建了演示该问题的测试程序
#include <iostream>
#include <string>
#include <pthread.h>
pthread_t thread[100];
using namespace std;
class tst {
public:
tst() {
//cout << \"~ Create\" << endl;
}
~tst() {
//cout << \"~ Delete\" << endl;
}
void calc() {
string TTT;
for (int ii=0; ii<100000; ii++) {
TTT+=\"abcdenbsdmnbfsmdnfbmsndbfmsndb \";
}
}
};
void *testThread (void *arg) {
int cnt=*(int *) arg;
cout << cnt << \" \";
tst *TEST=new tst;
TEST->calc();
delete TEST;
pthread_exit((void *)0);
}
int main (int argc, char * const argv[]) {
cout << \"---------------------------------------------------\" << endl;
sleep(5);
for (int oo=0; oo<100; oo++) {
pthread_create(&thread[oo], NULL, testThread, &oo);
pthread_detach(thread[oo]);
}
cout << endl;
cout << \"---------------------------------------------------\" << endl;
sleep(5);
for (int oo=0; oo<100; oo++) {
pthread_create(&thread[oo], NULL, testThread, &oo);
pthread_detach(thread[oo]);
}
cout << endl;
cout << \"---------------------------------------------------\" << endl;
sleep(5);
exit(0);
}
第一个“-”之后的内存使用量为364KB,第二个为19MB,第二个为33.5MB。
还有一件奇怪的事情-每次运行显示不同的内存使用情况,但大多数情况下,最后一个内存使用情况要比第二个“-”之后多50%。
我曾期望,如果删除类TEST(tst),那么字符串也将释放其内存-我发现线程不会这样做-这就是为什么我要创建新的tst,运行它并然后删除。
在我的程序中,这引起了一个大问题,因为我在每个线程中使用的字符串很少,并且一段时间后内存使用量超过了演出;-(
有什么选择如何在字符串后“清空”内存?
我已经尝试了TTT = \“ \”或TTT.clear()而不进行任何更改。
...我需要使用线程-它将在multicpu机器上运行,其中线程是使用它的“全功能”的唯一选择(据我所知)
没有找到相关结果
已邀请:
5 个回复
磁辫覆氓
函数退出后,ѭ1中的字符串使用的内存将被释放。删除每个“ 3”对象与它无关,因为没有类成员。 我认为您所看到的是可能正在运行200个线程。由于您分离了所有线程并且从不加入它们,因此您无法保证在开始下一个100之前,前100个线程实际上已经完成。 另外,由于您是通过追加来一次又一次地扩展这些字符串,而同时又在其他线程中分配内存,因此我想您的堆碎片确实非常糟糕。假设一个线程刚刚释放了一个256字节字符串的内存。其他线程已经在前面运行,它们都不再需要256字节的字符串了。现在,该空间已被浪费,但仍分配给程序。 一些可能有帮助的选项: 在将数据放入字符串之前,请使用
。这将有助于避免碎片问题,因为几乎所有字符串的大小都相同。 自定义的字符串分配器类。你可以自己写。 您可以用诸如jemalloc或tcmalloc之类的东西来替换堆分配器。 对于处理来来往往的客户端的服务器应用程序,您可以使用每个客户端的内存池来获得出色的性能。在一个块中分配一个大的内存池。使所有分配使用池(通过STL分配器参数),并且当客户端退出时释放整个池。
赣借
为字符串预分配内存。在这种情况下,您的字符串为(31 * 100,000)+ 1个字节长,因此您可以按以下方式修改
:
这将在单个连续的块中为字符串分配一次内存,并避免了您现在正遭受的很多碎片。在Valgrind下对该更改进行的快速测试表明,原始代码在整个过程的生命周期内总共分配了约1.5 GB;但修改后的版本确实分配了大约620 MB的内存。 同样值得注意的是,Valgrind没有发现任何内存泄漏。如果您认为程序中存在内存问题,那就总是尝试一下是个好主意:Valgrind home。
悸翠疮武昏
超可林
鞘垒飘
...我在项目中发现了几个小错误,但这是主要问题