【问题标题】:Boost Shared Pointers and Memory Management提升共享指针和内存管理
【发布时间】:2012-10-19 00:55:45
【问题描述】:

我最近才开始使用 boost,它提供的功能和 API 给我留下了深刻的印象。

在使用 boost::shared_ptr 时,当我用 Valgrind 检查程序时,我发现了相当多的“仍然可以访问”的内存泄漏。根据 Valgrind 的文档,这些都不是问题。但是,由于我过去只使用标准 C++ 库,因此我始终确保编写的任何程序都完全没有内存泄漏。

我的问题是,这些内存泄漏是否值得担心?我尝试使用 reset(),但是它只会减少引用计数,不会释放内存。我可以安全地忽略这些,或者以任何方式强制释放 boost::shared_ptr 分配的内存吗?

谢谢。

编辑1:

我在这段代码中使用了 apache thrift。使用 valigrind 进一步检查,使用选项 --show-reachable=yes,几乎所有的泄漏消息都类似于以下内容:

==6813== 24 bytes in 1 blocks are still reachable in loss record 3 of 21
==6813==    at 0x4C2B6CD: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so)
==6813==    by 0x5E7A783: CRYPTO_malloc (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==6813==    by 0x5EF524A: lh_insert (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==6813==    by 0x5E7BC17: ??? (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==6813==    by 0x5E7C268: ??? (in /lib/x86_64-linux-gnu/libcrypto.so.1.0.0)
==6813==    by 0x5BF43C5: SSL_CTX_free (in /lib/x86_64-linux-gnu/libssl.so.1.0.0)
==6813==    by 0x4E9574F: apache::thrift::transport::SSLContext::~SSLContext() (TSSLSocket.cpp:71)
==6813==    by 0x4E95768: apache::thrift::transport::SSLContext::~SSLContext() (TSSLSocket.cpp:74)
==6813==    by 0x4E96C08:  apache::thrift::transport::TSSLSocketFactory::~TSSLSocketFactory() (sp_counted_base_gcc_x86.hpp:145)
==6813==    by 0x4E96C98: apache::thrift::transport::TSSLSocketFactory::~TSSLSocketFactory() (TSSLSocket.cpp:369)
==6813==    by 0x42A986: void boost::checked_delete<apache::thrift::transport::TSSLSocketFactory>(apache::thrift::transport::TSSLSocketFactory*) (checked_delete.hpp:34)
==6813==    by 0x42ADE3: boost::detail::sp_counted_impl_p<apache::thrift::transport::TSSLSocketFactory>::dispose() (sp_counted_impl.hpp:78)

这是否意味着是节俭代码在泄漏内存?

谢谢。

【问题讨论】:

  • 你能提供一个最小的可编译示例来演示泄漏吗?
  • 通常shared_ptr 托管内存在引用计数变为零时被释放。如果不是这种情况,则可能有多种原因,具体取决于您的应用程序如何使用shared_ptr。最糟糕的是你可以在你的类结构中使用共享指针进行循环引用,在这种情况下,AFAIK 永远不会释放分配的内存。
  • @g-makulik 说了什么;找到解决方案的有效关键字是weak_ptr
  • @FredLarson:感谢您的建议。我会尝试发布一个可编译的示例,但很难在示例中获得相同的场景。

标签: c++ boost memory-leaks shared-ptr


【解决方案1】:

通常,如果内存仍然可以访问,则不是泄漏。如果您将泄漏定义为您使用 malloc/new 保留的一些内存,但您不能再释放它,如

//this leaks since p is unreachable outside the scope
int main() {
  char * p = (char*)malloc(10);
  return 0; 
}

您可能会遇到一种情况,即您的内存总是在增长,但从技术上讲这不是泄漏,例如你有一个全局列表,你总是把东西放进去,但从不把它们拿出来。 在这种情况下,列表内存是可以访问的,你 could 释放它。

话虽如此,通过粘贴在您问题中的调用堆栈,似乎引用的内存是 libcrypto 在销毁节俭 SSL 传输时完成的一些分配。

所以你的共享指针不是问题,很可能只是在 libcrypto 中使用的缓冲内存。

【讨论】:

  • +1。当我追溯泄漏的来源时,它们来自我正在使用的库。
【解决方案2】:

看看http://www.gnu.org/software/libc/manual/html_node/Statistics-of-Malloc.html#Statistics-of-Malloc

如果程序开头的uordblks 与末尾的相同,则说明没有泄漏。因为您已设法释放所有已分配的内存。

【讨论】:

  • 有趣。从atexit() 处理程序调用mallinfo() 是否合法?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2011-06-10
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-06-02
  • 1970-01-01
相关资源
最近更新 更多