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 recorderdetectorMain 实例之间的连接将使用排队连接,所以如果你真的以 1kHz 发出 UpdateVols 信号,那么我怀疑事件队列正在逐渐填满待处理请求——因此内存使用量不断增加。您可以尝试限制UpdateVols 信号的发射速率吗? 我现在就试试@G.M.是否有一些关于使用 emit 的文档以及这样做的频率如何?考虑到它的音频信号,我想把损失降到最低 【参考方案1】:

什么@G.M.在 cmets 中说有效。谢谢你

问题在于发射率。 1khz 太快了,积累了很多。

【讨论】:

我假设随着事件开始堆积,您只真正关心最近的事件。如果 Qt 提供了一种简单的方法来做到这一点,那就太好了。有关执行此操作的复杂方法,请参阅question。 谢谢你。我会通过它

以上是关于Qt 应用程序内存使用情况的主要内容,如果未能解决你的问题,请参考以下文章

Qt的内存管理

在vs中进行qt桌面应用开发时,编译器堆溢出的编译错误(error C1060编译器堆内存不足)

在vs中进行qt桌面应用开发时,编译器堆溢出的编译错误(error C1060编译器堆内存不足)

qt编程,怎么能避免内存泄露

Qt 4 - QuaZip - 文件大小限制和内存问题

Qt 信号槽 cv::Mat 无法读取内存访问冲突