标准::字符串使用的可用内存

Free memory used by a std::string

本文关键字:内存 字符串 标准      更新时间:2023-10-16

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

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

我有一个std::vector< queue_item_t >,其中填充了来自数据库查询的许多内容。

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

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

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

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);

某些字符串实现是写入时复制的。当从多个位置引用此类字符串时,将在写入时重新分配内存。

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

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

要释放内存,您可以只执行以下操作:

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

该方法shrink_to_fit()将很好地释放内存并为新值 my_queue_item.content(本例为 15 字节)分配足够小的空间。

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

如果要在同一queue_item_t中读取更多数据,它应该替换以前的字符串内容。

确定你没有泄露queue_item_t本身吗?