0

我正在用 C++ 开发一个贝叶斯推理采样器,它在树上传递了很多信息,并且这棵树是在智能指针(Boost 的 shared_ptr 和 weak_ptr)的帮助下实现的。

在推理期间(即运行一个较长的 C++ 函数 1-2 分钟),树发生了很大变化,创建和销毁了许多节点。

推理过程完全(100% 负载)占用处理器(一个线程,更准确地说)。由于某种原因,新内存(用于新节点)被占用,但旧内存没有被完全释放,这在 1-2 分钟的推理后导致内存溢出。

但是,如果我在推理过程中添加暂停,似乎程序会完全破坏旧对象,并且一切正常。

在我看来,原因是析构函数(或者更准确地说,它之后发生的事情,即内存释放)由于某种原因被延迟了。

请您告诉我:1)这似乎是一个真正的问题吗?2)如果是,在释放“足够的内存”时等待如何更好?什么是标准策略?

(程序在 Unix 上运行。)

4

3 回答 3

2

您观察到的内存问题似乎并不存在于 C++ 本身。如果 shared_ptr 释放它的内存,它会立即释放它,而不是以某种延迟的方式。但是,您的操作系统可能会在它认为合适的时候延迟“真正的”发布一段时间。在像 Windows 的“任务管理器”这样的程序中,您的程序可能会消耗越来越多的内存,而这只是操作系统为您保留的内存,但您实际上并没有占用。如果您的计算产生如此繁重的处理器负载,调度程序可能会延迟相当“不重要”的任务(如释放内存),直到有时间,以免妨碍更重要的事情,如您的计算。

然而,释放和分配内存是昂贵的。而且您似乎可以互换地释放和分配大量内存。您应该考虑通过自己的内存管理(如内存池等)或通过回收对象(即节点)本身来回收该内存,这意味着不是真正销毁它们,而是将它们返回给某个“节点池”并用新值重置它们。两者都可以与 shared_ptr 一起完成。

于 2013-01-22T09:37:46.687 回答
1

听起来你的树中有循环,即它shared_ptr同时用于子指针和父指针,这可以防止自动树节点破坏。使用普通指针可能会更好。

于 2013-01-22T09:46:05.823 回答
0

当最后一个指向对象的 shared_ptr 被销毁时,该对象立即被删除。所以你得到的听起来很奇怪。我能想象的唯一想法是您已将垃圾收集器附加到您的实现中......否则请仔细检查所有旧对象是否被销毁。

于 2013-01-22T09:32:30.307 回答