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 and
delete` 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.
精彩评论