我正在用C ++开发一个贝叶斯推理采样器,它在树上传递很多,这个树是在智能指针(Boost的shared_ptr和weak_ptr)的帮助下实现的。
在推理期间(即运行长时间的C ++函数1-2分钟),树的变化很大,创建并销毁了许多节点。
完全推理过程(100%负载)占用处理器(更准确地说是一个线程)。由于某种原因,新内存(对于新节点)正在被占用,但是旧内存没有被完全释放,这会在推断1-2分钟后产生内存溢出。
但是,如果我在推理过程中添加暂停,那么程序似乎完全破坏旧对象,并且一切正常。
对我来说,原因似乎是析构函数(或更确切地说,之后发生的事情,即内存释放)因某种原因而被推迟。
请告诉我: 1)这似乎是一个真正的问题吗? 2)如果是,那么在释放“足够的内存”时如何更好?什么是标准策略?
(该程序正在Unix上运行。)
答案 0 :(得分:2)
您观察到的内存问题似乎不在于C ++本身。如果shared_ptr释放其内存,它会立即释放,而不是以某种延迟方式。但是,您的操作系统可能会在其认为合适的情况下将“真实”版本延迟一段时间。在像Windows“任务管理器”这样的程序中,可能看起来你的程序消耗的内存越来越多,而这只是操作系统为你预留的内存,但实际上并没有占用。如果你的计算产生如此繁重的处理器负载,那么调度程序可能会延迟相当“不重要”的任务(比如释放内存),直到有时间,以免妨碍计算等更重要的事情。
但是,释放和分配内存非常昂贵。而且你似乎可以自由地分配大量内存。您应该考虑通过执行自己的内存管理(如内存池等)或通过回收对象(即节点)本身来回收该内存,这意味着不会真正销毁它们,而是将它们返回到某些“节点池”。并使用新值重置它们。两者都可以与shared_ptr一起完成。
答案 1 :(得分:1)
听起来你的树中有循环,即它对子指针和父指针使用shared_ptr
,这会阻止自动树节点破坏。使用普通指针可能会更好。
答案 2 :(得分:0)
当指向对象的最后一个shared_ptr被销毁时,该对象立即被删除。所以你听到的听起来很奇怪。我能想到的唯一想法是你已经为你的实现附加了一个垃圾收集器......否则请仔细检查所有旧对象是否被破坏。