获取Qt对象的大小

6

我正在使用Qt和C++,我需要找出特定Qt类的实例使用了多少内存,通常可以使用sizeof来完成,但在Qt中,每个类都持有指向另一个包含实际实现的类的指针,这个私有实现类的定义只存在于源代码中而不是头文件中。

我对Qt还不熟悉,也许有标准的方法来解决这个问题,如果没有,你有什么想法来解决吗?


6
你认为你为什么需要这样做? - anon
1
我需要知道是否可以创建成千上万个对象,或者该对象是否太大。 - Diaa Sami
3
@Diaa:尝试创建它们,并仔细检查错误。 - Evan Teran
3
好的,以下是翻译的结果:问题:QObject到底有多重?回答:QObject本身只是一个轻量级对象,它的额外负担来自于其它功能,如信号槽、元对象系统和属性系统。在实际应用中,这些额外的功能往往比QObject本身的开销更加显著。 - dtech
@anon 有些人没有无限的内存,实际上必须考虑这一点,不能编写臃肿的代码。QObject添加了很好的功能,但如果我们在嘲笑oom killer,它就不值得了。 - Freedom_Ben
4个回答

10

在标准C++中没有办法做到这一点,很少有框架支持类似的功能。原因相当简单-正如您所观察到的那样,一个对象可能包含指针,并且那些指针可能指向进一步包含指针的对象,依此类推。即使当您到达指针链的末尾时,也没有通用方法可以找出指针指向多少内存。

因此,您需要找到另一种解决问题的方法,我不认为这是首先要解决的正确问题。


7
由于相同类型的不同对象分配的内存量可能不同(例如,QSomething A可能能够重用缓存中的某些数据,而QSomething B可能必须单独分配它等),因此对于这个问题没有确切的答案。
我想你可以编写一个简单的测试程序,启动后分配N个相关对象,然后进入睡眠状态。在程序休眠时,使用任务管理器(或您喜欢的其他工具)查看进程使用的RAM数量。然后按Ctrl-C(或kill)停止该进程,并使用更大的N值再次运行它,并重复测量。重复此过程,最终您将了解进程的RAM分配随分配的项目数量增加而增长的情况,然后您可以进行一些代数运算,以获得每个对象的平均内存成本的大致估计。
请记住,启动进程时会有很多内存开销,因此从所有情况中减去N = 0的内存使用量,以便只测量对象的成本而不是环境开销。

5
问题并不仅限于Qt。考虑一下std::string使用了多少空间,它既不是sizeof(std::string),也不是std::string::size()
C++没有对这个问题的答案,因为这个问题很少有意义。

2
对于std::string,使用sizeof(std::string) +字符串长度可以得到几乎正确的数字。 人们应该知道对象有多重才能编写高效的应用程序。 我觉得奇怪的是,在允许低级编程并给你绝对控制的语言中,这样的问题很少有意义。 - Diaa Sami
1
仅举几个原因,它并不是那么可靠:小字符串优化、大小舍入、堆开销、COW。关于您的第二条评论,我还没有遇到过缺乏这些信息会妨碍我的情况。 - MSalters
@Diaa它确实给你绝对的控制权,但如果你想要那样的话,就不能使用像Qt或标准库这样的库-你必须编写自己的库。但是,没有这些库提供您所问的功能应该表明,这不是一个特别有用的功能来实现。 - anon
@Neil,@MSalters 感谢您们的回复,我理解你们的观点,但我并不信服。我想更深入地讨论这个问题,但评论并不是很适合这样做。 - Diaa Sami

2

我发现在创建超过几千个实例时,QObject通常比较重。

正如其他人提到的那样,通常最好的方法是尝试一下并观察结果。你甚至可以编写一个类似于以下的小应用程序:

int main(int argc, char **argv)
{
    QApplication app(argc, argv);
    QObject objects[5000];
    return app.exec();
}

在退出应用程序之前,请先测量内存使用情况。


将对象放在堆栈上不会反映在应用程序内存使用情况中,因为堆栈已经是预分配的内存块。此外,这不会给您QObject的实际大小,只会给出对象外壳的大小,您可以轻松地并且更准确地使用sizeof获取... - dtech

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接