8

我有一个struct看起来像这样的:

struct queue_item_t {
    int id;
    int size;
    std::string content;
};

我有一个std::vector< queue_item_t >从数据库查询中填充了许多这些的内容。

处理每个项目时,会从磁盘读取文件并将其内容放入content字符串成员中。该项目被处理(content被解析),我.clear()在字符串上执行,以免耗尽我所有的内存。

但是,这似乎并没有释放内存。我正在处理数十万个项目,最终,内存使用量将超出可用范围,并且应用程序被 Linux 杀死,原因是“内存不足”。

如何释放这些字符串使用的内存?

4

4 回答 4

15

std::string 和 std::vector 在 clear() 中不改变容器容量(=> 不释放容器内存)。每当需要压缩时(通常不需要),都应该使用下面的临时对象技巧。

my_queue_item.content.clear(); // clear
std::string(my_queue_item.content).swap(my_queue_item.content); // compact

当需要清理+压缩时,上面的代码可以变得更简单:

std::string().swap(my_queue_item.content);

一些字符串实现是写时复制的。这样的字符串,当从多个地方引用时,会在写入时重新分配内存。

于 2012-06-11T11:04:23.470 回答
1

clear不会释放字符串的所有内存(可能只是缓冲区)。它只会将字符串设置为空字符串。

如果你可以调用clear字符串,为什么不重用它呢?因此,无需创建新的queue_item_t,只需将其字符串成员替换为新值即可。

于 2012-06-11T11:06:14.617 回答
1

要释放内存,您可以这样做:

my_queue_item.content = "";
my_queue_item.content.shrink_to_fit();

该方法shrink_to_fit()将很好地释放内存并为新值my_queue_item.content(在这种情况下为 15 个字节)分配足够小的空间。

于 2013-08-18T12:55:28.180 回答
0

clear可能不会释放内存。它会在逻辑上将字符串设置为空字符串,但可能不会影响已分配的内存。

如果您正在将更多数据读入相同的queue_item_t,它应该替换以前的字符串内容。

你确定你没有泄露queue_item_t自己吗?

于 2012-06-11T11:09:53.053 回答