1

私のコンパイラ プロジェクトは深刻なメモリ消費をしています。そこで、どのクラスが最悪かを突き止められる方法を見つけたいと思います。それは私に次のようなものを与えるはずです:

--------------------------------------------------------------------
Class name, Instance count, Peak memory consumed

Circle, 223, 2230 k

Rectangle, 124, 3220 k

Line, 22322, 222322 k

....., ...,   .... .

私は長い間ウェブで検索してきましたが、これまでのところ結果はありません。:(

Devpartner ツールを試しました。私が知っているように、ネイティブ C++ を扱うことはできません。使い方がわからないからでしょうか?

何か提案はありますか?

4

3 に答える 3

2

メモリ リーク ディテクタまたはガベージ コレクタを使用できます。個人的にはBoehm GCをガベージコレクターとして使っていますが、リークディテクターとしても使えます。私の友人は、メモリ リークの検出に valgrind を使用しています。

カスタム オブジェクトからすべてのクラスを派生させることもできます。これは、割り当てられたすべてのオブジェクトを静的な std::set 構造体で追跡します。コンストラクタはこの構造体に「this」を挿入し、デストラクタはこれを削除します。次に、プログラムの最後で静的な Object::detectMemoryLeaks() を使用して、リークしているすべてのオブジェクトとその typeid(ptr).name() を出力できます。

編集:

過去数時間で自分のバージョンを自分のライブラリに実装しました。静的変数を除外したり、ポリモーフィック オブジェクトのサイズを自動的に決定したりする方法はまだ見つかっていません。また、Java のような異質なコードとガベージ コレクションの存在についてはご容赦ください:ヘッダー実装。コンストラクタ、デストラクタ、aliveObjects 静的属性、および listAliveObjects 静的メソッドを探します。コンセプトの要点を簡単につかむことができます。

出力例:

Frigo::Lang::Array<char> : 6 objects
Frigo::Lang::String : 6 objects
Frigo::Lang::Boolean : 2 objects
Frigo::Lang::Integer : 2 objects
Frigo::Math::Infinity : 1 objects
Frigo::Lang::Class : 1 objects

----

Frigo::Lang::Array<char> : 7 objects @ 0x1d33e18, 0x1d33e78, 0x1d33ed8, 0x1d33f38, 0x1d33f68, 0x1d33f98, 0x1d33fc8
Frigo::Lang::String : 7 objects @ 0x1d33e10, 0x1d33e70, 0x1d33ed0, 0x1d33f30, 0x1d33f60, 0x1d33f90, 0x1d33fc0
Frigo::Lang::Boolean : 2 objects @ 0x1d30fa8, 0x1d30fd8
Frigo::Lang::Integer : 2 objects @ 0x1d30e88, 0x1d30eb8
Frigo::Lang::Class : 1 objects @ 0x1d30f60
Frigo::Math::Infinity : 1 objects @ 0x41a110

----

Frigo::Lang::Array<char> : 6 objects
    Frigo::Lang::Array<char>@3b3e78
    Frigo::Lang::Array<char>@3b3ed8
    Frigo::Lang::Array<char>@3b3f38
    Frigo::Lang::Array<char>@3b3f68
    Frigo::Lang::Array<char>@3b3f98
    Frigo::Lang::Array<char>@3b3fc8
Frigo::Lang::String : 6 objects
    Frigo::Lang::Boolean
    Frigo::Lang::Class
    Frigo::Lang::Integer
    Hello World!
    true
    false
Frigo::Lang::Boolean : 2 objects
    true
    false
Frigo::Lang::Integer : 2 objects
    987
    123
Frigo::Math::Infinity : 1 objects
    Frigo::Math::Infinity@41a110
Frigo::Lang::Class : 1 objects
    Frigo::Lang::Class@3b0f60

----

Frigo::Lang::Array<char> : 7 objects
    @ 0x1cd3e18 : Frigo::Lang::Array<char>@1cd3e18
    @ 0x1cd3e78 : Frigo::Lang::Array<char>@1cd3e78
    @ 0x1cd3ed8 : Frigo::Lang::Array<char>@1cd3ed8
    @ 0x1cd3f38 : Frigo::Lang::Array<char>@1cd3f38
    @ 0x1cd3f68 : Frigo::Lang::Array<char>@1cd3f68
    @ 0x1cd3f98 : Frigo::Lang::Array<char>@1cd3f98
    @ 0x1cd3fc8 : Frigo::Lang::Array<char>@1cd3fc8
Frigo::Lang::String : 7 objects
    @ 0x1cd3e10 : Frigo::Lang::Boolean
    @ 0x1cd3e70 : Frigo::Lang::Class
    @ 0x1cd3ed0 : Frigo::Lang::Integer
    @ 0x1cd3f30 : Frigo::Math::Infinity
    @ 0x1cd3f60 : Hello World!
    @ 0x1cd3f90 : true
    @ 0x1cd3fc0 : false
Frigo::Lang::Boolean : 2 objects
    @ 0x1cd0fa8 : true
    @ 0x1cd0fd8 : false
Frigo::Lang::Integer : 2 objects
    @ 0x1cd0e88 : 987
    @ 0x1cd0eb8 : 123
Frigo::Lang::Class : 1 objects
    @ 0x1cd0f60 : Frigo::Lang::Class@1cd0f60
Frigo::Math::Infinity : 1 objects
    @ 0x41b110 : Frigo::Math::Infinity@41b110
于 2011-08-09T16:00:58.230 に答える
0

もちろん、動的に割り当てられたメモリについて話していることを願っています。

メモリプロファイリングツールを使用する必要があります。
そうでない場合はnew and、独自のクラスのdelete`演算子をオーバーロードし、同じ中にメモリカウントメカニズムを実装する必要があります。

于 2011-08-09T15:31:12.283 に答える
0

クラスのコンストラクターでクラスで宣言された static int をアトミックにインクリメント (win32 では InterlockedIncrement) し、クラスのデストラクタでアトミックにデクリメントすることができます。次に、別の静的メソッドを使用して、カウントと消費されたメモリの合計を取得できます。

疑わしいクラスの数が少ないと仮定すると、これには合理的な量のコーディング作業が必要になることはありません。

于 2011-08-09T23:26:49.617 に答える