gpt4 book ai didi

c++ - std::string 内存管理

转载 作者:塔克拉玛干 更新时间:2023-11-02 23:56:52 33 4
gpt4 key购买 nike

我在使用 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,运行它然后删除.

在我的程序中,这导致了一个大问题,因为我在每个线程中使用了很少的字符串,一段时间后内存使用量超过了 gig ;-(

是否有任何选项如何在字符串后“清空”内存?

我试过 TTT=""或 TTT.clear() 没有任何改变。

...我需要使用线程——它将在多 cpu 机器上运行,其中线程是使用它的“全功率”的唯一选择(据我所知)

最佳答案

calc()中字符串占用的内存会在calc函数退出后释放。删除每个tst对象与它无关,因为没有类成员。

我认为您看到的是可能有 200 个线程在运行。由于您分离了所有线程并且从不加入它们,因此您无法保证在开始下一个 100 个之前前 100 个实际上已完成。

此外,因为您通过附加同时在其他线程中分配内存来一遍又一遍地扩展这些字符串,我想您的堆碎片确实真的 真的 不好。假设一个线程刚刚为一个 256 字节的字符串释放了内存。其他线程已提前运行,它们不再需要 256 字节的字符串。该空间现在只是被浪费了,但仍分配给了程序。

一些可能有帮助的选项:

  • 在将数据放入字符串之前使用 .reserve(your_largest_expected_string_size)。这将有助于避免碎片问题,因为几乎所有字符串的大小都相同。
  • 一个自定义的字符串分配器类。你可以自己写。
  • 您可以用 jemalloc 或 tcmalloc 之类的东西替换您的堆分配器。
  • 对于处理来来往往的客户端的服务器应用程序,您可以使用每个客户端的内存池获得出色的性能。在一个 block 中分配一个大内存池。让所有分配都使用池(通过 STL 分配器参数),并在客户端退出时释放整个池。

关于c++ - std::string 内存管理,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5682713/

33 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com