Qt 应用程序内存使用情况
Posted
技术标签:
【中文标题】Qt 应用程序内存使用情况【英文标题】:Qt Application Memory Usage 【发布时间】:2021-01-09 12:10:07 【问题描述】:我正在开发一个涉及使用实时、连续、音频输入的应用程序,为此我使用的是 portaudio。我首先创建了简单的 cli 版本以进行设置,并且 cli 版本中的内存使用情况似乎很好。在 CLI 版本中,当录制打开时,除了初始缓冲区之外没有分配额外的内存。
但是,在将相同代码从 CLI 应用到 GUI(为此,我使用 Qt)的过程中,我注意到随着录制的进行,应用程序使用的内存不断增加(大约3 mb/秒)。由于我的应用程序在未定义的时间内涉及音频输入,因此这种行为可能非常致命,因此,我开始从代码中剥离段,以检查哪个区域负责使用该内存。 (请注意,在 cli 版本中没有观察到这种行为,并且在 qt 中使用了几乎相同的代码,除了添加了 Q_OBJECT 宏)
我尝试了一段时间,但找不到任何东西。
我对使用 Qt 比较陌生,非常感谢一些帮助
我的小部件应用程序头文件
#ifndef DETECTORMAIN_H
#define DETECTORMAIN_H
#include <QMainWindow>
#include <QThread>
#include <QPointer>
#include "utils/rectools.h" /*Custom header file, the implementation of
which has been carried over from the cli version
which worked with constant memory usage.
Contains a class Recorder with the Q_OBJECT macro*/
QT_BEGIN_NAMESPACE
namespace Ui class detectorMain;
QT_END_NAMESPACE
class detectorMain : public QMainWindow
Q_OBJECT
public:
detectorMain(QWidget *parent = nullptr);
~detectorMain();
private slots:
void on_beginRecordingButton_clicked();
void on_stopRecordingButton_clicked();
void updateVolLabel(std::string);
private:
Ui::detectorMain *ui;
QPointer<Recorder> recorder;
QThread* thread;
;
#endif // DETECTORMAIN_H
源文件
#include "detectormain.h"
#include "ui_detectormain.h"
detectorMain::detectorMain(QWidget *parent)
: QMainWindow(parent)
, ui(new Ui::detectorMain)
ui->setupUi(this);
recorder = new Recorder;
thread = new QThread;
recorder->moveToThread(thread);
thread->start();
ui->beginRecordingButton->setEnabled(true);
ui->stopRecordingButton->setEnabled(false);
connect(recorder, SIGNAL(UpdateVols(std::string)), this, SLOT(updateVolLabel(std::string)));
detectorMain::~detectorMain()
delete ui;
void detectorMain::on_beginRecordingButton_clicked()
ui->beginRecordingButton->setEnabled(false);
ui->stopRecordingButton->setEnabled(true);
recorder->begin_recording();
void detectorMain::on_stopRecordingButton_clicked()
recorder->stop_recording();
ui->beginRecordingButton->setEnabled(true);
ui->stopRecordingButton->setEnabled(false);
void detectorMain::updateVolLabel(std::string vol)
ui->VolLabel->setText(QString::fromStdString(vol));
QCoreApplication::processEvents();
函数 Recorder::begin_recording() 发出 UpdateVols(std::string) 其中 UpdateVols 是 Recorder 类中的一个信号。它以相当快的速度发射(每毫秒大约 1 次)。这是否与内存使用量增加有关? 在 CLI 版本中,我可以根据需要计算任何内容,这是 CLI 版本和 Qt 版本之间代码的最大区别。
begin_recording() 函数执行完成后内存使用量并没有减少,这让我很困惑。
例如,应用程序以 9 mb 的内存使用量开始,当 begin_recording() 运行 10 秒时增加到大约 39,之后不做任何事情时保持在 39 mb。
如果是快发射率,我假设不再发射时内存使用会恢复正常。
另外,在上面的代码中,当点击 beginRecordingButton 时,应用程序变得无响应,但在函数 recorder->begin_recording() 执行完成后恢复。我想这与内存不断增加有关,但我不太确定。
我认为错误存在于我如何使用 QThread 对象并将记录器对象移动到它的某个地方,但我不确定如何修复它。
在找出内存使用量增加的过程中,我尝试运行一个只有按钮和标签的裸应用程序,根本不涉及记录器类。在简单地以零功能打开此应用程序时,只要显示非零 CPU 利用率,内存使用量就会持续增加约 0.5mb。增加后即使cpu利用率为0也不会下降。
总的来说,我想问一下,
1)如何解决内存使用量不断增加的问题? (我认为错误不在于 Recorder 类,因为相同的代码在没有 qt 的情况下在常量内存中运行)
2)最后一段提到的行为是否正常?
【问题讨论】:
在哪个操作系统上?什么样的计算机(单核 RasberryPi 或多核 Linux/x86-64 笔记本电脑,例如运行 Debian...)?请在您的问题中提供一些minimal reproducible example(因此简化您的代码,但请提供一些main
功能)。对于 Linux,另请参阅 linuxatemyram.com 并考虑使用 valgrind.org
recorder
和 detectorMain
实例之间的连接将使用排队连接,所以如果你真的以 1kHz 发出 UpdateVols
信号,那么我怀疑事件队列正在逐渐填满待处理请求——因此内存使用量不断增加。您可以尝试限制UpdateVols
信号的发射速率吗?
我现在就试试@G.M.是否有一些关于使用 emit 的文档以及这样做的频率如何?考虑到它的音频信号,我想把损失降到最低
【参考方案1】:
什么@G.M.在 cmets 中说有效。谢谢你
问题在于发射率。 1khz 太快了,积累了很多。
【讨论】:
我假设随着事件开始堆积,您只真正关心最近的事件。如果 Qt 提供了一种简单的方法来做到这一点,那就太好了。有关执行此操作的复杂方法,请参阅question。 谢谢你。我会通过它以上是关于Qt 应用程序内存使用情况的主要内容,如果未能解决你的问题,请参考以下文章
在vs中进行qt桌面应用开发时,编译器堆溢出的编译错误(error C1060编译器堆内存不足)