开发者

How can I statistic instance numbers of each class and the memory they consumed in the peak time in native C++ project

My compiler project has a serious memory-consuming. So I want to find a method that can find out which class is the worst one. It should give me something like bellow:

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

Circle, 223, 2230 k

Rectangle, 124, 3220 k

Line, 22322, 222322 k

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

I have searched for a long time on the web but no result so far. :(

I have tried Devpartner t开发者_开发技巧ools. It can't deal with native C++ as I know. Does that because of I don't know how to use it?

Do you have any suggestion?


You could use a memory leak detector or a garbage collector. Personally I use the Boehm GC as garbage collector, but it is possible to use it as a leak detector. My friend uses valgrind for memory leak detection.

It is also possible to derive all of your classes from a custom Object, which keeps track of ALL allocated objects in a static std::set structure; the constructor inserts "this" into this structure, the destructor removes it. Then you can use a static Object::detectMemoryLeaks() at the end of your program to print out all leaking objects and their typeid(ptr).name().

Edit:

I implemented my version in the last few hours into my library. Found no way yet to exclude static variables, or to automatically determine the size of a polymorphic object. Also, please excuse the java-like alienish code and the presence of garbage collection: header and implementation. Look for the constructor, the destructor, the aliveObjects static attribute and the listAliveObjects static method. You can get the gist of the concept easily.

Example outputs:

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


Ofcourse I hope you are talking of Dynamically allocated memory.

You should use memory profiling tools.
If not you should overload the new anddelete` operators for your own class and implement the memory count mechanism in the same.


You can try atomically incrementing (InterlockedIncrement in win32) a static int declared in your class in the class' constructor and atomically decrementing it in the class' destructor. Then you can use another static method to retrieve the count and the total memory consumed.

Assuming you have a small number of suspect classes, this shouldn't take more than reasonable amount of coding effort.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜