矢量<string>在超出范围后不清除内存
vector<string> does not clear memory after out of scope
我遇到了以下问题,我真的不确定是我错了还是这是一个非常奇怪的错误。我填充了一个巨大的字符串数组,并希望它在某个点被清除。以下是的一个最小示例
#include <string>
#include <vector>
#include <unistd.h> //sleep
#include <iostream>
int main(){
{
std::vector<std::string> strvec;
for(long i = 0; i < 1000000; ++i){
std::string out = "This is gonna be a long string just to fill up the memory used by this fucking pthreadn";
strvec.push_back(out);
}
std::cout << "finished loading 1stn";
sleep(10); // to monitor any changes
}
std::cout << "out of scopen";
sleep(10);
return 0;
}
我的问题是,如果我用"top"监控内存使用情况,内存使用量只会减少很小的一部分(我认为这可能是矢量开销),但大部分似乎没有释放。怎么回事?我用"long-long"测试了同样的场景,但这里一切都很顺利。
std::vector引用声明,如果包含的值没有指针,则会调用析构函数。字符串似乎不正确。。。
我感谢每一个答案。
(为了方便:我使用的是带有g++4.7.2的debian-linux-64Bit)
编辑:谢谢你到目前为止的回答。
到目前为止,我已经用vagrind massif描述了堆的使用情况,并且(是的,实际上正如预期的那样)它在应该的时候得到了适当的释放。但是,为什么我实际上看到一个大整数的用法发生了变化,而字符串(也是顶部的whithin)却没有?
我需要对此有一点谨慎,因为我需要能够在特定时间为多线程服务器应用程序释放内存,该应用程序可能会运行数周或更长时间而不会重新启动。我什么时候真正知道C++内存管理器何时决定给操作系统一些内存?
这是使用top
命令的特定情况,而不是std::vector
的特定情况。问题是数据结构释放的内存没有释放回操作系统,top
命令监视内存使用情况的级别。操作系统为程序提供的内存将保留在程序中,直到C++的内存管理器决定是时候将一些内存释放回操作系统为止。
原因是从操作系统中分配内存相对昂贵,并且需要以相对较大的块来完成。C++运行库的内存管理器从操作系统"批发"获得内存,然后根据需要将其打包到程序的各个部分。
如果您想验证内存是否确实被回收,请使用一个在较低级别监视内存使用情况的工具,如valgrind
。
即使您正确释放了内存,标准库也不需要将内存释放回操作系统。
因此,例如,当您第一次分配所有内存时,库会从操作系统中分配一堆虚拟内存地址空间(可能是mmap(2)
)并将其分配出去。但是,当您处理完该内存时,它会挂在虚拟地址空间上,假设您稍后可能希望该内存返回,因此它不会调用munmap(2)
来取消映射虚拟地址空间。
因此,即使从程序的角度来看,所有的内存都被正确释放了,操作系统看到的只是你分配了一堆虚拟内存,但从未释放过。这就是为什么top(1)
报告你的内存使用量没有减少,但这没什么好担心的。当你的程序再次需要内存时,它会从你已经拥有的虚拟地址空间中分配内存,所以在所有内存用完之前,你不会看到明显的内存使用量增加。
如其他答案中所述,内存仍然可用于进程,并且在程序退出之前不会释放内存。如果你想要一个能做到这一点的分配器,你可以使用jemalloc进行检查,它可以将其释放回操作系统,在facebook等可扩展的多线程应用程序中非常有用,但与其他任何应用程序一样,还有其他成本。
- 为什么在全局范围内使用"extern int a"似乎不行?
- 尝试通过多个向量访问变量时,向量下标超出范围
- 错误:未在此范围内声明'reverse'
- 正在将指针转换为范围
- 使用std::transform将一个范围的元素添加到另一个范围中
- 在基于范围的for循环中使用结构化绑定声明
- 如何计算数据类型的范围,例如int
- 为什么 const std::p air<K,V>& 在 std::map 上基于范围的 for 循环不起作用?
- 在C++中查找范围的长度
- 如何设置一个范围来提取我想要获得的信息
- 并行用于C++17中数组索引范围内的循环
- 为左值和右值的包装器实现C++范围
- 清除前检查矢量
- 求出有多少个数字是完美平方,而sqrt()是L,R范围内的素数
- 关于:C++中异常对象的范围:为什么我没有得到副本?
- 超出范围时使用对象
- 清除向量时,stl 向量中的 stl 向量是否超出范围?
- Do 函数在退出范围时清除动态内存
- 矢量<string>在超出范围后不清除内存
- 未初始化的互斥对象超出范围--清除