Виталий Антипов
Виталий Антипов17. März 2018 13:58

Вопросы по использованию памяти

Добрый день! Столкнулся с проблемой резкого роста потребления памяти программой и пытаюсь в этом разобраться. Представим пример:

int main(int argc, char *argv[])
{
...
QObject* root = engine.rootObjects()[0];
ListModel *model = new ListModel();
DataMapper *mapper = new DataMapper();
QObject::connect(root, SIGNAL(qmlSignal()), model, SLOT(updateModel()));
mapper->setModel(model);
engine.rootContext()->setContextProperty("mapper", mapper);
...
}
Вызываемый слот:
void ListModel::updateModel()
{
    QObject* stack = this->parent()->findChild<QObject*>("stackView");
    QString name=(stack->property("name")).toString();
    this->setQuery(" SELECT Base.id, Base.Company, Base.Number FROM Base WHERE Base.Name = " + name );
}
Абстрактный main.qml:
ApplicationWindow {
    id: window
    siqnal qmlSignal()
    StackView {
       id: stackView
       objectName: "stackView"
       property string name: "Leonid"
           Component.onCompleted: {
               stackView.push(window1) //стартовое окно
               }
       Component {
            id: window1
            Window1{
                id: window1_
            }
        }
        Component {
            id: window2
            Window2 {
                id: window2_
            }
        }
}
}
В начальном окне Window1:
Item {
   ...
   Button {
   ...
   onClicked: stackView.replace(window2)
   }
}
Окно отображения данных Window2:
Item {
   ...
Component.onComplited {
   qmlSignal()
   mapper.addMapping(text_company, (0x0100+2), "text")
   mapper.addMapping(text_number, (0x0100+3), "text")
   }
Button {
onClicked: stackView.replace(window2) } }
То есть в интерфейсе грузимся с каким-то Window1, на котром кнопочка, по нажатию на которую Window1 заменяется на Window2, при загрузке которого отправляется сигнал на отработку функции updateModel(). В результате получаем модель model, на основе которой получится mapper из которого забираем данные в какие-то дочерние элементы Window2.
Теперь нажмем на кнопку в Window2 - произойдет замена этого компонента StackView на Window1. Я вот почему-то думал, что родителем для mapper и model является window2 - ведь в нем они вызываются. Но при уничтожении window2 они остаются жить. В чем я не прав? И второй вопрос... в реальном проекте в mapper передается модель с 33 значениями, но при вызове mapper.addMapping() потребление оперативки растет на сотни мегабайт и приложение падает. От чего зависит размер выделяемой памяти в куче?
Рекомендуємо хостинг TIMEWEB
Рекомендуємо хостинг TIMEWEB
Stabiles Hosting des sozialen Netzwerks EVILEG. Wir empfehlen VDS-Hosting für Django-Projekte.

Magst du es? In sozialen Netzwerken teilen!

6
Виталий Антипов
  • 17. März 2018 17:16
  • (bearbeitet)

Это какая-то жесть. Вместо model и mapper данные записал в QStringList и передал в интерфейс. Аналогично память начала расти скачками 100 Мб->155 Мб->215 Мб->285 Мб->302 Мб и словил

terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
terminate called recursively
Программа неожиданно завершилась.
С model и mapper было то же самое. Думал что проблема с динамическим выделением памяти, ан нет...
    Evgenii Legotckoi
    • 17. März 2018 17:21

    Добрый день!
    У модели и маппера изначально вообще нет родителя. Вы же не передаёте указатель на родителя, когда выделяете память в куче. А то, что окно имеет доступ к ним, так это лишь благодаря тому, что Вы зарегистрировали их в качестве контекста в QML движке. Полагаю, что в данном случае никаких прав родительствования у этих объектов вообще не изменяется. А объект Window2 или Window1 не являются для них порождающими, поэтому и не могут быть родителями.


    А вот, что касается addMapping(), то там по ходу утечка памяти где-то... на сотни мегабайт возрастания не должно быть. Либо утечка памяти, либо зацикливание. Запустите в дебагере и посмотрите, где упадёт. Вполне возможно, что в C++ части падать будет.

      А какую версию Qt сейчас используете?

        Qt 5.10.1.

          Дебагер не помогает. Пишет неизвестный процесс остановил программу. А сейчас выдало:

          Out of memory  in scenegraph\coreapi\qsggeometry.cpp, line 678
          terminate called without an active exception
          Out of memory  in c:\Users\qt\work\install\include/QtCore/qvector.h, line 552
          terminate called recursively
          terminate called recursively
          Но у меня нет такой папки c:\Users\qt.
          В релиз сборке приложение не падает.
          Все-таки нашел источник проблемы. Я в интерфейс накидал много огромных моделей данных, но если их заранее уменьшить то проблем нет.
          И все-таки хотелось бы вернуться к первому вопросу. Если модель и маппер не имеют родителя, то какой смысл им выделять динамическую память? ведь после вызова они будут жить до конца жизни программы и весь смысл в куче пропадает.

            Можете не выделять )) Я тогда просто не очень обратил внимание на этот нюанс. Конкретно в данном случае, можно создать в стеке и передать ссылку в setContextProperty вместо указателя.

              Kommentare

              Nur autorisierte Benutzer können Kommentare posten.
              Bitte Anmelden oder Registrieren
              Letzte Kommentare
              A
              ALO1ZE19. Oktober 2024 18:19
              Fb3-Dateileser auf Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
              ИМ
              Игорь Максимов5. Oktober 2024 17:51
              Django – Lektion 064. So schreiben Sie eine Python-Markdown-Erweiterung Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
              d
              dblas55. Juli 2024 21:02
              QML - Lektion 016. SQLite-Datenbank und das Arbeiten damit in QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
              k
              kmssr9. Februar 2024 05:43
              Qt Linux - Lektion 001. Autorun Qt-Anwendung unter Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
              Qt WinAPI - Lektion 007. Arbeiten mit ICMP-Ping in Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
              Jetzt im Forum diskutieren
              J
              JacobFib17. Oktober 2024 13:27
              добавить qlineseries в функции Пользователь может получить любые разъяснения по интересующим вопросам, касающимся обработки его персональных данных, обратившись к Оператору с помощью электронной почты https://topdecorpro.ru…
              JW
              Jhon Wick2. Oktober 2024 01:52
              Indian Food Restaurant In Columbus OH| Layla’s Kitchen Indian Restaurant If you're looking for a truly authentic https://www.laylaskitchenrestaurantohio.com/ , Layla’s Kitchen Indian Restaurant is your go-to destination. Located at 6152 Cleveland Ave, Colu…
              КГ
              Кирилл Гусарев27. September 2024 19:09
              Не запускается программа на Qt: точка входа в процедуру не найдена в библиотеке DLL Написал программу на C++ Qt в Qt Creator, сбилдил Release с помощью MinGW 64-bit, бинарнику напихал dll-ки с помощью windeployqt.exe. При попытке запуска моей сбилженной программы выдаёт три оши…
              F
              Fynjy22. Juli 2024 14:15
              при создании qml проекта Kits есть но недоступны для выбора Поставил Qt Creator 11.0.2. Qt 6.4.3 При создании проекта Qml не могу выбрать Kits, они все недоступны, хотя настроены и при создании обычного Qt Widget приложения их можно выбрать. В чем может …

              Folgen Sie uns in sozialen Netzwerken