3

我正在做一个项目,使用 Qt 和一些定制的 QDialogs 供用户输入。由于我的开发盒的硬件限制,我想监控我的应用程序的内存使用情况。我如何执行对话框。

1 void MainWindow::callDialog() {
2     DlgPopConfig dialog(&theApp->cfgPop, m_fnPopCfg, this);
3     dialog.exec();
4     m_fnPopCfg = dialog.fileName();
5     lbl_fnPopCfg->setText(m_fnPopCfg);
6 }

由于对话框是一个局部变量,我希望它在堆栈上创建并在函数结束后立即销毁(在第 5 行之后)。当应用程序反复打开和关闭对话框时,它的内存使用量会上升,并且它永远不会返回初始值 ['Memory (Working Set)' and 'Memory (Private Working Set)'任务管理器的列]。我使用了Application Verifier,启用了所有基本测试,并且没有显示错误。内存模式如下所示(数值仅由说明组成):

  • 应用程序启动(工作集 = 12000K,私有集 = 6000K)
  • 打开 Dialog-1(工作集 = 14000K,私有集 = 7000K)
  • 关闭对话框(工作集 = 12010K,私有集 = 6005K)
  • 打开 Dialog-2(工作集 = 14020K,私有集 = 7000K)
  • 关闭对话框(工作集 = 12010K,私有集 = 6008K)
  • 打开 Dialog-3(工作集 = 14080K,私有集 = 7010K)
  • 关闭对话框(工作集 = 12040K,私有集 = 6008K)
  • ...

那么,有什么想法可以追踪问题的根本原因吗?(实际上,我在使用 QFileDialog 的静态方法时也遇到了类似的问题getOpenFileName,并且在这里getSaveFileName找到了一些讨论,但似乎没有解决)

编辑我在我的对话框中使用 QFormLayout,并通过添加小部件layout->addRow("label text", mywidget);,我怀疑对象销毁是否无法干净地删除标签。

编辑我用 QDialog 创建了一个测试程序,有十个 QLineEdits,使用相同的添加小部件策略。问题依然存在。(如果我经常创建和关闭对话框,这个测试程序会出现问题,每秒说 10 次)

主窗口.h

#include <QMainWindow>
#include <QPushButton>
#include <QDialog>
class MainWindow : public QMainWindow
{
    Q_OBJECT
public:
    explicit MainWindow(QWidget *parent = 0);
private:
    QPushButton * button;
private slots:
    void button_click();
};
class Dialog : public QDialog
{
    Q_OBJECT
public:
    explicit Dialog(QWidget *parent = 0);
};

主窗口.cpp

#include "mainwindow.h"
#include <QApplication>
#include <QFormLayout>
#include <QLineEdit>
#include <QLabel>

MainWindow::MainWindow(QWidget *parent):QMainWindow(parent)
{
    button=new QPushButton(this);setCentralWidget(button);
    connect(button,SIGNAL(clicked()),SLOT(button_click()));
}
void MainWindow::button_click()
{
    Dialog d(this);
    d.exec();
}
Dialog::Dialog(QWidget *parent):QDialog(parent)
{
   QFormLayout*layout=new QFormLayout(this);
   setLayout(layout);
   for (int i = 0; i < 10; i++)
   {
       layout->addRow(QString("%1").arg(i+1), new QLineEdit(this));
   }
}
int main(int c,char *argv[])
{
    QApplication a(c,argv);
    MainWindow w;
    w.show();
    return a.exec();
}

平台

  • Win 7 x64, MinGW 4.7.2 x64 (rubenvb-build), 4GB 内存
  • Qt 4.8.5(使用上述工具链本地构建)
  • Qt-Creator 2.6.1(使用上述工具链本地构建)
4

1 回答 1

3

晚了几个月,但这可能会帮助下一个遇到这个问题的人。我正在使用 PySide,但有相同的内存泄漏。结果有两个选项,具体取决于您需要从对话框中返回的信息:

1) 完成后安排删除对话框。

在 Python 中,这看起来像:

dialog = MyDialog(self)
dialog.exec_()
# Do other things with dialog
dialog.deleteLater()

它在您的 C++ 代码中应该看起来相似:

void MainWindow::button_click()
{
    Dialog d(this);
    d.exec();
    // Do other things with d
    d.deleteLater()
}

2) 设置 WA_DeleteOnClose 属性。

我最终将其包含在自定义对话框的构造函数中:

    self.setAttribute(PySide.QtCore.Qt.WA_DeleteOnClose)

在您的 C++ 代码中应该如下所示:

Dialog::Dialog(QWidget *parent):QDialog(parent)
{
   QFormLayout*layout=new QFormLayout(this);
   setLayout(layout);
   setAttribute(Qt::WA_DeleteOnClose);
   for (int i = 0; i < 10; i++)
   {
       layout->addRow(QString("%1").arg(i+1), new QLineEdit(this));
   }
}

这两个都为我修复了内存泄漏,除了如果我连续多次快速打开/关闭对话框,它偶尔会泄漏 4kb。很抱歉以 Python 为中心的答案——希望这能将人们引向正确的方向。

于 2013-06-12T18:25:11.787 回答