我在类中有一个递归方法来计算某些阶段(无论这是什么)。如果它注意到一个阶段的成功概率很低,则通过将其存储在队列中来延迟该阶段,并且程序将在稍后寻找延迟阶段。它抓取一个阶段,复制数据以便工作并删除阶段。
程序运行正常,但我遇到了内存问题。由于这个程序是随机的,它可能会延迟多达1000万个阶段,导致8到12 GB的内存使用(或更多,但在此之前崩溃)。程序似乎永远不会在到达递归函数的调用堆栈结束之前为已删除的阶段释放内存。
class StageWorker
{
private:
queue<Stage*> delayedStages;
void perform(Stage** start)
{
// [long value_from_stage = (**start).value; ]
delete *start;
// Do something here
// Delay a stage if necessary like this
this->delayedStages.push(new Stage(value));
// Do something more here
// Look for delayed stages like this
Stage* front = this->delayedStages.front();
this->delayedStages.pop();
this->perform(&front);
}
}
我使用指向指针,因为我认为内存没有被释放,因为有一个指向舞台的指针(前面*)。所以我用一个指向指针的指针,所以我可以删除它。但它似乎不起作用。如果我在性能监视器(在Windows上)上观察内存使用情况,它就像这样:
我标记了递归调用的结束。这也只是一个示例图。实际数据,但在非常小的情况下。
任何想法如何在到达调用堆栈结束之前释放不再使用的sage的内存?
修改
我遵循了一些建议并删除了指针。所以现在它看起来像这样:
class StageWorker
{
private:
queue<Stage> delayedStages;
void perform(Stage& start)
{
// [long value_from_stage = start.value; ]
// Do something here
// Delay a stage if necessary like this
this->delayedStages.push(Stage(value));
// Do something more here
// Look for delayed stages like this
this->perform(this->delayedStages.front());
this->delayedStages.pop();
}
}
但这没有改变,内存使用情况与以前相同。
如上所述,这可能是一个监控问题。有没有更好的方法来检查确切的内存使用情况?
答案 0 :(得分:0)
刚刚回答这个问题:
Mats Petersson(非常感谢)在评论中提到它可能是监视内存使用的问题。
事实上这正是问题所在。我在编辑中提供的代码(在通过引用替换指针之后)正确释放了空间,但它没有返回给操作系统(在本例中为Windows)。所以从显示器看起来空间没有被释放。
但后来我做了一些实验,发现应用程序重用了释放的内存,因此不必向操作系统请求更多内存。
所以监视器显示的是在第一次调用此函数结束后,使用所需的递归函数返回整个内存的最大内存量。