4

我有一个非常复杂的数据对象,它使用了一个字符串映射

typedef std::map<std::string, unsigned int> Event;
typedef std::pair<double, Event> EventGroup;
std::vector<EventGroup> eventVector;

这是一个始终在后台运行以侦听传入消息的程序。每次有一个新的 EventGroup 进入时,它可以在地图中包含任意数量的字符串,我将它添加到向量中。

// New data came in
eventVector.push_back(newEventGroup);

时不时地我会在这个向量上做一个擦除

//Flush some of the data because it's old
// it's been determined that the index to erase at is flushIndex
eventVector.erase(eventVector.begin(), eventVector.begin()+flushIndex);

通常这往往是数据的前 5%。

我一直注意到的是似乎存在内存泄漏。内存使用量开始时约为 50 MB……但在速度太慢和崩溃之前最终接近 1 GB。我听说进行擦除是一项昂贵的操作,但这可能是内存泄漏的原因吗?我是否错过了一些释放地图使用的内存的方法?

4

1 回答 1

4

在不知道您的自定义类型的作用或外观的情况下(它们是否泄漏内存?)很难说。但是您应该注意,从向量中擦除元素实际上不会释放任何内存,它使向量已经分配的区域可用于添加到该向量的不同元素。换句话说,向量的保留空间保持不变。

所以,如果你将一个向量增加到几百万个元素,删除其中的 90%,并期望得到一堆内存,你会感到失望。释放向量保留的内存的方法(在它被销毁之前永远不会回馈任何东西)是做交换习语的事情:

std::vector<EventGroup>(eventVector).swap(eventVector);

我不记得复制构造函数在这里如何工作的确切细节。它的行为应该与您执行此操作完全相同:

std::vector<EventGroup>(eventVector.begin(), eventVector.end()).swap(eventVector);

你仍然无法控制它用了多少空间,但是如果你释放了很多空间并且它会在很长一段时间内保持释放......这应该会给系统一些未知数量的内存。

请记住,这是一项昂贵的操作(这就是 std::vector 不只是为您执行此操作的原因),因此仅在您需要时执行此操作。

于 2012-05-02T18:56:52.563 回答