为啥我的 unordered_map 越来越大
Posted
技术标签:
【中文标题】为啥我的 unordered_map 越来越大【英文标题】:why is my unordered_map getting bigger and bigger为什么我的 unordered_map 越来越大 【发布时间】:2020-12-27 18:43:25 【问题描述】:我用的是unordered_map,key是string,value是一个class IpsegInfo。 我读取了一个文件并使用文件数据来更新map中的值,map的大小总是一样的,但是内存中的map空间越来越大。
我的代码每 30 分钟从文件中更新一次地图,文件有 1000 万行,长度从未改变,只有数据会改变。所以我的地图长度也总是一千万。文件物理大小为 500MB,第一次加载后 unordered_map 内存大小为 4GB,但几个小时后,map 大小变为 50GB,并且不断变大,我想我应该是在某个地方发生了内存泄漏。
我的代码如下:
class IpsegInfo
public:
string country;
string province;
string isp;
string asn;
IpsegInfo();
IpsegInfo(string country, string province, string isp, string asn);
~IpsegInfo();
;
//one thread is doing the map refresh. other threads read the map for quick access.
unordered_map<string, IpsegInfo> IpsegMap::map;
void refresh()
while(1)
string line;
string delim = ",";
ifstream ipsegFile("/opt/test/ipseg.txt");
if(ipsegFile.is_open())
while (getline(ipsegFile,line) )
trim(line);
vector<string> ss = comUtil.split(line,delim);
IpsegInfo *info = new IpsegInfo(ss[1],ss[2],ss[3],ss[4]);
map[ss[0]] = *info;
ipsegFile.close();
sleep(60*30);
【问题讨论】:
这块内存在哪里被释放:IpsegInfo *info = new ...
@Jarvis map
不是关键字,实际上是 C++ 程序完全合法且合法的变量名。
但map[ss[0]]
是IpsegInfo
类型的对象。它不是一个指针。这不是你分配的东西。在refresh
函数中,info
是一个指向你已经分配的东西的指针,但你从来没有delete
它。解决方法是根本不使用new
或临时的info
变量,直接赋值给map[ss[0]]
。
@Jack 你需要做的是找出哪个数据结构拥有你分配的内存,以及何时释放它。
@Someprogrammerdude 问题不在于不必要的局部变量info
,而在于分配的内存,它永远不会被释放。
【参考方案1】:
IpsegInfo *info = new IpsegInfo(ss[1],ss[2],ss[3],ss[4]);
map[ss[0]] = *info;
在这里,您使用 new 创建一个 IpsegInfo
。这意味着您还应该使用delete
将其删除。
相反,您只需覆盖它,就会造成内存泄漏。使用 RAII 自动管理您的数据:
IpsegInfo info = IpsegInfo(ss[1],ss[2],ss[3],ss[4]); // no pointers!
map[ss[0]] = info;
【讨论】:
甚至不需要info
变量。
@Someprogrammerdude 是的。我把它留在那里,这样更改会更容易看到。另外:using namespace std
被认为是不好的做法!
@Someprogrammerdude 我刚试过,它有效,非常感谢!为什么在使用new IpsegInfo()时没有被覆盖,但是没有new就被覆盖了?顺便说一句,我应该在插入之前使用 map.erase() 吗?
@Jack — 当您使用new
创建一个对象时,您有责任在完成后销毁它。如果您不想发生内存泄漏,则必须在某个时候将其删除。您可以在分配给map[ss[0]]
后使用delete info;
消除泄漏,但此答案中的解决方案是更好的方法。让编译器处理簿记以销毁对象。以上是关于为啥我的 unordered_map 越来越大的主要内容,如果未能解决你的问题,请参考以下文章
std::unordered_map::operator[] - 为啥有两个签名?