Russian Qt Forum
Ноябрь 26, 2024, 02:47 *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

Войти
 
  Начало   Форум  WIKI (Вики)FAQ Помощь Поиск Войти Регистрация  

Страниц: [1]   Вниз
  Печать  
Автор Тема: Qt и потребление памяти  (Прочитано 9286 раз)
Jabberwokky
Гость
« : Январь 14, 2009, 20:30 »

Добрый день, я недавно начал изучать Qt и столкнулся с такой проблемой:

В одном из примеров рассказывается как создать простейшие виды layout'ов. Программа, получаемая на выходе занимает аж 19 метров памяти, при этом не делая ничего, кроме отображения нескольких кнопок и текстовых полей.

Это, к сожалению, очень много.  Грустный  Не подскажете, почему так происходит и можно ли уменьшить потребление памяти?

Текст примера можно найти в Assistant -> Basic Layouts Example, но на всякий случай прилагаю его к сообщению.

Код:
Dialog.h:

#ifndef DIALOG_H
 #define DIALOG_H

 #include <QDialog>

 class QAction;
 class QDialogButtonBox;
 class QGroupBox;
 class QLabel;
 class QLineEdit;
 class QMenu;
 class QMenuBar;
 class QPushButton;
 class QTextEdit;

 class Dialog : public QDialog
 {
     Q_OBJECT

 public:
     Dialog();

 private:
     void createMenu();
     void createHorizontalGroupBox();
     void createGridGroupBox();
     void createFormGroupBox();

     enum { NumGridRows = 3, NumButtons = 4 };

     QMenuBar *menuBar;
     QGroupBox *horizontalGroupBox;
     QGroupBox *gridGroupBox;
     QGroupBox *formGroupBox;
     QTextEdit *smallEditor;
     QTextEdit *bigEditor;
     QLabel *labels[NumGridRows];
     QLineEdit *lineEdits[NumGridRows];
     QPushButton *buttons[NumButtons];
     QDialogButtonBox *buttonBox;

     QMenu *fileMenu;
     QAction *exitAction;
 };

 #endif

-----------------------------------------------------------------
Dialog.cpp:

#include <QtGui>

 #include "dialog.h"

 Dialog::Dialog()
 {
     createMenu();
     createHorizontalGroupBox();
     createGridGroupBox();
     createFormGroupBox();

     bigEditor = new QTextEdit;
     bigEditor->setPlainText(tr("This widget takes up all the remaining space "
                                "in the top-level layout."));

     buttonBox = new QDialogButtonBox(QDialogButtonBox::Ok
                                      | QDialogButtonBox::Cancel);

     connect(buttonBox, SIGNAL(accepted()), this, SLOT(accept()));
     connect(buttonBox, SIGNAL(rejected()), this, SLOT(reject()));

     QVBoxLayout *mainLayout = new QVBoxLayout;
     mainLayout->setMenuBar(menuBar);
     mainLayout->addWidget(horizontalGroupBox);
     mainLayout->addWidget(gridGroupBox);
     mainLayout->addWidget(formGroupBox);
     mainLayout->addWidget(bigEditor);
     mainLayout->addWidget(buttonBox);
     setLayout(mainLayout);

     setWindowTitle(tr("Basic Layouts"));
 }

 void Dialog::createMenu()
 {
     menuBar = new QMenuBar;

     fileMenu = new QMenu(tr("&File"), this);
     exitAction = fileMenu->addAction(tr("E&xit"));
     menuBar->addMenu(fileMenu);

     connect(exitAction, SIGNAL(triggered()), this, SLOT(accept()));
 }

 void Dialog::createHorizontalGroupBox()
 {
     horizontalGroupBox = new QGroupBox(tr("Horizontal layout"));
     QHBoxLayout *layout = new QHBoxLayout;

     for (int i = 0; i < NumButtons; ++i) {
         buttons[i] = new QPushButton(tr("Button %1").arg(i + 1));
         layout->addWidget(buttons[i]);
     }
     horizontalGroupBox->setLayout(layout);
 }

 void Dialog::createGridGroupBox()
 {
     gridGroupBox = new QGroupBox(tr("Grid layout"));
     QGridLayout *layout = new QGridLayout;

     for (int i = 0; i < NumGridRows; ++i) {
         labels[i] = new QLabel(tr("Line %1:").arg(i + 1));
         lineEdits[i] = new QLineEdit;
         layout->addWidget(labels[i], i + 1, 0);
         layout->addWidget(lineEdits[i], i + 1, 1);
     }

     smallEditor = new QTextEdit;
     smallEditor->setPlainText(tr("This widget takes up about two thirds of the "
                                  "grid layout."));
     layout->addWidget(smallEditor, 0, 2, 4, 1);

     layout->setColumnStretch(1, 10);
     layout->setColumnStretch(2, 20);
     gridGroupBox->setLayout(layout);
 }

 void Dialog::createFormGroupBox()
 {
     formGroupBox = new QGroupBox(tr("Form layout"));
     QFormLayout *layout = new QFormLayout;
     layout->addRow(new QLabel(tr("Line 1:")), new QLineEdit);
     layout->addRow(new QLabel(tr("Line 2, long text:")), new QComboBox);
     layout->addRow(new QLabel(tr("Line 3:")), new QSpinBox);
     formGroupBox->setLayout(layout);
 }

----------------------------------------------------------------------------
main.cpp:

#include <QApplication>

#include "dialog.h"

int main(int argc, char *argv[])
{
    QApplication app(argc, argv);
    Dialog dialog;
    return dialog.exec();
}

Спасибо.
« Последнее редактирование: Январь 14, 2009, 20:32 от Jabberwokky » Записан
Rcus
Гость
« Ответ #1 : Январь 14, 2009, 20:50 »

Qt 4.4.3, полет нормальный.
Записан
Jabberwokky
Гость
« Ответ #2 : Январь 14, 2009, 20:53 »

Rcus, может дело в том, что у вас Линукс?

У меня есть мысль, что так много памяти уходит на загрузку динамических библиотек в память, но я с ними только учусь работать и поэтому разбираюсь в этом плохо.  В замешательстве
Записан
Rcus
Гость
« Ответ #3 : Январь 14, 2009, 20:58 »

Дело в том, как вы считаете память. При загрузке приложения исполняемый файл и все разделяемые библиотеки отображаются в память. Отображение в память конечно еще не означает, что именно столько оперативной памяти используется. Второй фактор это способ учета памяти занимаемой разделямыми библиотеками. Если вы пользуетесь стандартным taskmgr то он учитывает в статистике потребления памяти память занимаемую библиотеками (если я ничего не перепутал). И по мне так это вполне нормально при динамической сборке.
Записан
Jabberwokky
Гость
« Ответ #4 : Январь 14, 2009, 21:02 »

Rcus, Спасибо.
Записан
Jabberwokky
Гость
« Ответ #5 : Январь 14, 2009, 23:33 »

Ещё один вопрос (спрошу здесь, чтобы не плодить темы). Пример всё тот же.

Если добавить ещё один QLineEdit, а на кнопку рядом с ним повесить QFileDialog::getExistingDirectory(), то мы получаем стандартный диалог виндоус для выбора файла.

Проблема в том, что на этот диалог тратится ещё три метра памяти, которые после закрытия диалога не особождаются.

Наверное, логично было бы вызывать деструктор, но ведь я не создаю объекта QFileDialog.  Непонимающий

Код:
Код:

dialogButton = new QPushButton(tr("Choose..."));

connect(dialogButton, SIGNAL(clicked()), this, SLOT(execFileDialog()));

void Dialog::execFileDialog()
{
    QString dir = QFileDialog::getExistingDirectory(0, tr("Open Directory"));
    directoryLine->setText(dir);
}

Записан
Rcus
Гость
« Ответ #6 : Январь 14, 2009, 23:44 »

для нативных диалогов под windows используются диалоги предоставляемые shell32.dll, скорее всего поэтому.
Записан
Jabberwokky
Гость
« Ответ #7 : Январь 15, 2009, 00:12 »

Спасибо.

Хм, проверил на некоторых других программах, не использующих Qt. Действительно, точно такое же поведение, память, к-ю показывает task manager, не освобождается. Не замечал никогда.
Записан
Detonator
Гость
« Ответ #8 : Январь 15, 2009, 00:30 »

А смысл ее освобождать, ведь она в дальнейшем снова может потребоваться. Тем более система вам выделяет виртуальное адресное пространство, а не реальную память. Страницы памяти будут предоставлены по необходимости, а если освободите и больше к ним обращаться не будете то они просто уйдут в своп.
Записан
lswa
Гость
« Ответ #9 : Май 13, 2009, 03:51 »

Приветствую! Набрел на тему в поисках ответа на свой вопрос: под Windows при вызове статической функции QDialog::getExistingDirectory(...) и последующего закрытия приложения оно виснет в списке задач, пока вручную не удалишь его. Исследования показали, что именно эта функция подвешивает программу.

Как-нибудь с этим можно бороться? В Linux'е все работает нормально...
Записан
pastor
Administrator
Джедай : наставник для всех
*****
Offline Offline

Сообщений: 2901



Просмотр профиля WWW
« Ответ #10 : Май 13, 2009, 11:55 »

показывай код
Записан

Integrated Computer Solutions, Inc. (ICS)
http://www.ics.com/
beak
Гость
« Ответ #11 : Июнь 04, 2009, 09:12 »

Тоже обнаружил адское сжирание памяти в QFileDialog::getExistingDirectory
IBM Rational Purify на одной машине показывает 141 кб а на другой 7 кб, везде стоит VS9 и Qt4.5.1, разница только в том что в первом случае есть зашаренные диски. кто нибудь подскажет как подлечить это?
Записан
Rcus
Гость
« Ответ #12 : Июнь 04, 2009, 10:21 »

/*пожимает плечами*/
Valgrind обычно пишет трейс стека вызовов при обнаружении утечки когда работает с memcheck, а без стека чего гадать?
Записан
Tonal
Гость
« Ответ #13 : Июнь 04, 2009, 13:25 »

Винда при открытии файлового диалога ещё и несколько потоков запущает.
А выбор директории через COM-овские сервисы Explorer-а работает.
Так что если хочется это безобразие обуздать, то нужно писать свои, полностью Qt-ёвые диалоги.
Записан
Страниц: [1]   Вверх
  Печать  
 
Перейти в:  


Страница сгенерирована за 0.08 секунд. Запросов: 22.