【问题标题】:Memory Allocation Profiling in C++C++ 中的内存分配分析
【发布时间】:2010-10-16 13:15:03
【问题描述】:

我正在编写一个应用程序,并且惊讶地发现它的总内存使用量已经太高了。我想分析我的应用程序的动态内存使用情况:堆中有多少种对象,哪些函数创建了这些对象?另外,每个对象使用了多少内存?

有没有简单的方法来做到这一点?我在 linux 和 windows 上工作,所以任何平台的工具都足够了。

注意:我不关心这里的内存泄漏。

【问题讨论】:

    标签: c++ memory-management profiling


    【解决方案1】:

    试试gperftools - 它可以:

    • 一次性分析代码的特定部分或整个程序。
    • 通过可视化有向图表示数据,显示确切的函数调用及其继承。
    • 专注于可视化图表中的特定代码区域。
    • 显示转储之间的差异。
    • 显示分配的空间而不是使用的空间 - 所有这些都是通过同一个转储完成的。

    而且几乎不影响程序效率。

    【讨论】:

    【解决方案2】:

    MTuner - 免费的 C/C++ 内存分析器。说明如下:

    MTuner 是一个多平台内存分析、泄漏检测和分析工具,支持 MSVC、GCC 和 Clang 编译器。功能包括:基于时间轴的内存活动历史、强大的过滤、带有完整源代码的手动检测 SDK、通过命令行使用的持续集成支持、内存泄漏检测等等。使用 GCC 或 Clang 交叉编译器分析任何软件目标平台。内置对 Windows、PlayStation 4 和 PlayStation 3 平台的支持以及基于 Windows 的交叉编译器所针对的平台。

    【讨论】:

    • 如何提交错误报告?我试过 Mtuner,它在启动带有长命令行的可执行文件时崩溃。有 github 仓库吗?
    • 在尝试加载大的 .MTuner 文件 (~9Gb) 时也会崩溃。您是否尝试一次将整个文件加载到内存中?您是否检查代码上的内存分配失败?
    • 没有 github repo,它是闭源的。请随时向我发送有关这些崩溃的更多信息,我会修复它们/看看。
    • 如何联系您?
    【解决方案3】:

    你试过Valgrind吗?它是用于 Linux 的分析工具。它有一个名为 Memcheck 的内存检查器(用于内存泄漏和其他内存问题),但它还有一个名为 Massif 的堆分析器。

    【讨论】:

    【解决方案4】:

    我刚刚发布了一个 win32 本机内存分析器 MemPro,作为免费测试版。 http://www.puredevsoftware.com/MemPro.htm。它连接到 new/delete 并将数据发送到外部应用程序,您可以在其中以各种不同的方式查看分配。希望对您有所帮助。

    【讨论】:

      【解决方案5】:

      对于简单的统计,只是为了找出所有内存的使用情况,您可以添加这样的模板:

      template<class T>
      class Stats {
        static int instance_count;
      public:
        Stats() {
          instance_count++;
        }
        ~Stats() {
          instance_count--;
        }
        static void print() {
          std::cout << instance_count << " instances of " << typeid(T).name() <<
              ", " << sizeof(T) << " bytes each." << std::endl;
        }
      };
      
      template<class T>
      int Stats<T>::instance_count = 0;
      

      然后你可以把它作为基类添加到你怀疑有很多实例的类中,并打印出当前内存使用的统计信息:

      class A : Stats<A> {
      };
      
      void print_stats() {
        Stats<A>::print();
        Stats<B>::print();
        ...
      }
      

      这并没有向您显示对象在哪些函数中被分配,也没有提供太多细节,但它可能足以找到浪费内存的位置。

      【讨论】:

      • 如果您这样做,请记住这不是线程安全的。您可以使用 std::atomic(如果您有 C++11)或 boost::atomic 进行增量/减量。
      【解决方案6】:

      来自Game Programming Gems Volume 8(Safari Book 预览链接)的第 4.6 章详细介绍了 Ricky Lung 的高级内存分析器,它可以以分层调用堆栈的方式显示分配统计信息,但支持多线程。

      【讨论】:

      • 章节不是立即可见的,你有没有强制订阅按钮或免费试用的真实预览链接?
      【解决方案7】:

      对于 Windows,请检查“crtdbg.h”中的函数。 crtdbg.h 包含内存分配函数的调试版本。它还包含检测内存泄漏、损坏、检查堆指针的有效性等功能。

      我认为以下功能会对您有用。

      _CrtMemDumpStatistics _CrtMemDumpAllObjectsSince

      以下 MSDN 链接列出了堆状态报告函数和示例代码 http://msdn.microsoft.com/en-us/library/wc28wkas(VS.80).aspx

      【解决方案8】:

      Game Programming Gems Volume 2 (Amazon link) 的第 1.10 章详细介绍了 Peter Dalton 的一个简单但有效的插入式调试内存管理器,它在您转储日志时提供了一组不错的统计信息。

      【讨论】:

        【解决方案9】:

        刚刚在AQtime site 上看到他们对“分配分析”有很好的支持。

        【讨论】:

          【解决方案10】:

          你可以试试http://www.softwareverify.com/cpp/memory/index.html的内存验证器

          这是我遇到的用于分析内存使用情况的最佳工具之一。 30 天评估版可供免费下载。

          【讨论】:

            【解决方案11】:

            您可以做几件事。最简单的就是链接一个调试malloc库;有许多可用,具体取决于您的环境的详细信息(例如,google 用于 Windows 的 _malloc_dbg。)

            第二种选择是可以在C++中重载newdelete;使用跟踪内存分配和使用的新函数可以重载基本的 new 和 delete。

            【讨论】:

              【解决方案12】:

              在之前的工作中,我们使用了一个名为“Purify”的工具。它是由 Rational/IBM 制造的产品。我不认为这是一个免费工具,但我记得它非常好。以下是一些信息:

              http://en.wikipedia.org/wiki/IBM_Rational_Purify

              【讨论】:

              • Purify 告诉您内存损坏和泄漏,而不是分配对象的大小
              猜你喜欢
              • 2014-10-25
              • 1970-01-01
              • 2010-12-11
              • 2010-11-07
              • 2022-01-21
              • 1970-01-01
              • 2012-01-24
              相关资源
              最近更新 更多