我在 C++ 的应用程序中使用 boost::shared_ptr 。内存问题确实很严重,应用程序占用大量内存。

但是,因为我将每个新对象放入shared_ptr中,所以当应用程序退出时,无法检测到内存泄漏。

一定有类似的东西 std::vector<shared_ptr<> > 持有资源的池。调试时如何知道谁拥有shared_ptr?

逐行检查代码很困难。代码太多了...

非常感谢!

有帮助吗?

解决方案

您可以不知道,只看着shared_ptr,其中“兄弟指针”是。您可以测试一个是unique()或获取use_count(),其中其它方法的。

其他提示

在流行普遍使用的shared_ptr的几乎不可避免地导致不希望的和看不见的存储器占用。

循环引用是一个公知的原因,它们中的一些可以是间接的并且很难被发现尤其是在复杂的代码是由一个以上的程序员制作;程序员可以决定不止一个对象需要另一个的引用,速战速决,没有时间检查所有代码,看看他是否关闭循环。这种危险被无限低估。

少很好理解是未发布的参考文献的问题。如果一个对象被共享出来很多shared_ptrs那么就不会被破坏,直到他们中的每一个归零或超出范围。这是很容易忽视这些引用的一个,并与你以为你已经完成了与对象存储潜伏着看不见的结束。

虽然严格来说这些不是内存泄漏(它将所有在程序退出之前被释放)它们只是作为有害和更难以检测。

这些问题是由于有利的假声明的后果: 1.声明你真的想成为一个所有权的shared_ptr什么。 scoped_ptr的是正确的,但随后其他任何引用该对象必须是原始指针,可以保留为悬空。 2.声明你真的想成为一个被动的观测基准为shared_ptr的是什么。 weak_ptr的是正确的,但那么你必须将其转换成share_ptr你想用它每一次的麻烦。

我怀疑你的项目是什么样的麻烦,这种做法可以让你成为一个很好的例子。

如果你有一个内存密集型应用程序,你真的需要单一的所有权,使您的设计可以明确控制对象的寿命。

使用单所有权opObject = NULL;肯定会删除对象,它现在会做的。

使用共享所有权spObject = NULL; ........谁知道?......

我们所做的悬空或循环智能指针引用的一种解决方案是自定义智能指针类以添加仅调试簿记功能。每当智能指针添加对对象的引用时,它都会获取堆栈跟踪并将其放入映射中,该映射的每个条目都跟踪

  1. 正在分配的对象的地址(指针指向的内容)
  2. 每个智能指针对象的地址持有对该对象的引用
  3. 每个智能指针构造时对应的堆栈跟踪

当智能指针超出范围时,其在映射中的条目将被删除。当指向对象的最后一个智能指针被销毁时,指针对象将删除其在映射中的条目。

然后我们有一个具有两个功能的“跟踪泄漏”命令:“[重新]启动泄漏跟踪”(清除整个地图并启用跟踪(如果尚未启用))和“打印打开引用”,显示自发出“启动泄漏跟踪”命令以来创建的所有未完成的智能指针引用。由于您可以看到这些智能指针产生的堆栈跟踪,因此您可以轻松地准确地知道谁在阻止您的对象被释放。当它打开时,它会减慢速度,所以我们不会让它一直打开。

这是一个相当大的工作量来实现,但如果你有一个经常发生这种情况的代码库,那么绝对是值得的。

您可能遇到经由循环共享指针内存泄漏。会发生什么事是你的共享对象可持有的其他共享对象,最终导致回原来的引用。当这种情况发生的周期保持所有引用计数为1,即使没有其他人可以访问的对象。该解决方案是弱指针

尝试重构了一些代码,使所有权由使用弱指针,而不是在一些地方共享指针的更明确表示。

当你的类层次结构看它可以确定哪个类真的应该持有一个共享的指针,这仅仅只需要弱者,这样就可以避免周期,如果有任何,如果“真正的”所有者对象被破坏, “非所有者”的对象应该已经走了。如果事实证明,某些对象失去指针太早,你不得不考虑对象销毁顺序您的应用程序,并修复它。

你显然持有到引用你的对象你的应用程序中。这意味着你是故意的,让事情在内存中。这意味着,你没有内存泄漏。内存泄漏是当存储器被分配,然后不保持它的地址的引用。

基本上,你需要看看你的设计,并弄清楚为什么你保持这么多的对象和数据在内存中,以及如何将其最小化。

,你有一个伪内存泄漏的一种可能性是要创建更多的对象比你认为你是。尝试把断点上包含一个“新”的所有语句。看看比你认为它会在您申请正在建设更多的对象,然后通过该代码读取。

但问题是我们没有那么多的内存泄漏,因为它是你的应用程序设计的问题。

我去,如果你是在Windows上建议使用UMDH。这是一个非常强大的工具。使用它发现每笔交易/时间段,你希望被释放,然后发现是谁在持有它们的分配。

有位于该SO答案的更多信息 查找引起智能指针的内存泄漏

这是不可能告诉什么从程序内的对象自己的shared_ptr。如果你是在Linux上,一个肯定的方式来调试内存泄漏是 Valgrind的工具 - 虽然它不会直接回答你的问题,它会告诉其中分配内存,这通常是解决问题就足够了。我想Windows有相当的工具,但我不知道哪一个是最好的。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top