2

gprofを使用して(C ++)プログラムによるメモリ消費量を把握しようとしています。プログラムにはGUIがなく、完全にCLIベースです。

今、私はgpr​​ofを初めて使用するので、gprofの実行方法とスポット時間の消費方法を教えてくれたチュートリアルをいくつか読みました。

ただし、特定のクラスのセットによるメモリ消費量を調べる必要があります。多くの種類のプログラムがあるとしましょうA, ..., Z。次に、プログラムを実行して、クラスのオブジェクトによって使用された累積メモリの数を確認しますA, E, I, O, U(たとえば)。

このタスクにどのように取り組むことができるか、アイデアや指針はありますか?
私はgpr​​ofだけを検討しているわけではなく、仕事を成し遂げるあらゆる(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 に答える