如何统计原生 C++ 中每个类的实例数量以及峰值时间消耗的内存?项目

发布于 2024-11-28 13:40:29 字数 406 浏览 0 评论 0原文

我的编译器项目有严重的内存消耗。所以我想找到一种方法,可以找出哪个类是最差的。它应该给我类似下面的内容:

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

Circle, 223, 2230 k

Rectangle, 124, 3220 k

Line, 22322, 222322 k

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

我在网上搜索了很长时间,但到目前为止还没有结果。 :(

我尝试过 Devpartner 工具。据我所知,它不能处理本机 C++。这是因为我不知道如何使用它吗?

你有什么建议吗?

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 tools. 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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

你是年少的欢喜 2024-12-05 13:40:29

您可以使用内存泄漏检测器或垃圾收集器。我个人使用 Boehm GC 作为垃圾收集器,但也可以将其用作泄漏检测器。我的朋友使用 valgrind 进行内存泄漏检测。

还可以从自定义对象派生所有类,该对象在静态 std::set 结构中跟踪所有分配的对象;构造函数将“this”插入到该结构中,析构函数将其删除。然后,您可以在程序末尾使用静态 Object::detectMemoryLeaks() 打印出所有泄漏对象及其 typeid(ptr).name()。

编辑:

我在过去几个小时内将我的版本实现到我的库中。尚未找到排除静态变量或自动确定多态对象大小的方法。另外,请原谅类似 java 的外星人代码和垃圾收集的存在: header实现。查找构造函数、析构函数、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

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
不知所踪 2024-12-05 13:40:29

当然,我希望您谈论的是动态分配的内存。

您应该使用内存分析工具。
如果没有,您应该为您自己的类重载 new 和 delete 运算符,并在其中实现内存计数机制。

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.

吃不饱 2024-12-05 13:40:29

您可以尝试在类的构造函数中原子地递增(win32 中的 InterlockedIncrement)在类中声明的静态 int 并在类的析构函数中原子地递减它。然后您可以使用另一个静态方法来检索计数和消耗的总内存。

假设您有少量可疑类,那么这不应该花费超过合理数量的编码工作。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文