2

我正在尝试使用 gprof 计算我的(C++)程序的内存消耗。该程序没有 gui,它完全基于 cli。

现在,我是 gprof 的新手,所以我阅读了一些教程,它们教会了我如何运行 gprof 并发现时间消耗。

但是,我需要找出一组特定类的内存消耗。假设有一个程序有多种类型,A, ..., Z. 现在我想运行我的程序并查看类的对象使用了多少累积内存A, E, I, O, U(例如)。

你们有什么想法或指示我可以如何完成这项任务吗?
我不是专门考虑 gprof,我对任何可以完成工作的 (fos) 软件持开放态度。

当然,我已经在 google 和 stackoverflow.com 上搜索过这个问题的任何答案,但是要么我使用了错误的关键字,要么没有人遇到这个问题。

编辑:关于手动执行此操作的建议很明显。当然,我可以将它编码到应用程序中,但它涉及大量我不想更改的类。另外,我想知道总内存消耗,所以我不能只计算所有创建的对象,因为我必须单独跟踪对象的大小。

Edit2:我修改了DeadMG 的建议,我只需要继承它。它工作得很好,所以,如果有人有类似的问题,试试这个。

class GlobalObjectCounter {
  public: 
    struct ClassInfo {
      unsigned long created;
      unsigned long destroyed;
      unsigned short size;
      ClassInfo() : created(0), destroyed(0), size(0) {}
      ClassInfo(unsigned short _size) : created(0), destroyed(0), size(_size) {}
      void fmt(std::ostream& os) {
        os << "total: " << (this->created) << " obj = " << (this->created*this->size) << "B; ";
        os << "current: " << (this->created-this->destroyed) << " obj = " << ((this->created-this->destroyed) * this->size) << "B; ";
      }
    };
  protected:
    static std::map<std::string,ClassInfo> classes;
    GlobalObjectCounter() {}
  public:
    static void dump(std::ostream& os) {
      for (std::map<std::string,ClassInfo>::iterator i = classes.begin(); i != classes.end(); ++i) {
        os << i->first << ": ";
        i->second.fmt(os);
        os << "\n";
      }
    }
};

template <class T> class ObjectCounter : public GlobalObjectCounter {
  private:
    static ClassInfo& classInfo() {
      static ClassInfo& classInfo = classes[std::string("") + typeid(T).name()];
      classInfo.size = sizeof(T);
      return classInfo;
    }
  public:
    ObjectCounter() {
      classInfo().created++;
    }
    ObjectCounter(ObjectCounter const& oc) {
      classInfo().created++;
    }
    ObjectCounter& operator=(const ObjectCounter&) {}
    ~ObjectCounter() {
      classInfo().destroyed++;
    }
};

地图查找有点讨厌,我承认,但我没有勇气为每个类存储迭代器。主要问题是您必须为每个计数类显式初始化它。如果您知道如何做得更好,请告诉我如何做。

4

3 回答 3

4

我不知道 gprof 甚至试图处理内存使用问题。显而易见的替代方案是valgrind. 如果您只关心总内存使用量,您也可以自己完成这项工作(重载::operator new::operator delete跟踪程序请求了多少内存)。当然,您可能有一些代码通过其他方式获取内存(例如,直接调用类似的东西sbrk),但这是相当不寻常的。但是,它们不会尝试跟踪静态分配和/或堆栈使用情况。

于 2010-08-27T14:52:43.067 回答
3

琐碎的。

template<typename T> class Counter {
    static int count = 0;
    Counter() { count++; }
    Counter(const Counter&) { count++; }
    Counter& operator=(const Counter&) {}
    ~Counter() { count--; }
};
class A : Counter<A> {
    static int GetConsumedBytes() {
        return sizeof(A) * count;
    }
};

如果 A 的使用涉及动态内存,那么这个解决方案可以改进。您还可以覆盖全局运算符 new/delete。

于 2010-08-27T14:54:32.980 回答
1

GlibC 提供有关堆内存分配的统计信息。看看mallinfo。您可能会在执行期间的不同点获得统计数据,并了解正在使用的内存量。

于 2010-08-27T15:41:02.080 回答