3

ユーザー入力用にカスタマイズされた QDialogs を使用して Qt を使用するプロジェクトを行っています。開発ボックスのハードウェアの制約により、アプリのメモリ使用量を監視したいと考えています。ダイアログの実行方法。

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);。オブジェクトの破棄でラベルをきれいに削除できないかどうかは疑問です。

編集同じ add-widget 戦略を使用して、QDialog に 10 個の QLineEdit があるテスト プログラムを作成しました。問題はまだ存在します。(ダイアログを頻繁に作成して閉じると、このテスト プログラムで問題が発生します。1 秒間に 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 RAM
  • Qt 4.8.5 (上記のツールチェーンを使用してネイティブにビルド)
  • Qt-Creator 2.6.1 (上記のツールチェーンを使用してネイティブにビルド)
4

1 に答える 1

3

数か月遅れていますが、これは、この問題に遭遇した次の人を助けるかもしれません. 私は PySide を使用していますが、同じメモリ リークがありました。ダイアログから取得する必要がある情報に応じて、2 つのオプションがあることが判明しました。

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 に答える