Виталий Антипов
Виталий АнтиповMarch 17, 2018, 1:58 p.m.

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

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

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() потребление оперативки растет на сотни мегабайт и приложение падает. От чего зависит размер выделяемой памяти в куче?
We recommend hosting TIMEWEB
We recommend hosting TIMEWEB
Stable hosting, on which the social network EVILEG is located. For projects on Django we recommend VDS hosting.

Do you like it? Share on social networks!

6
Виталий Антипов
  • March 17, 2018, 5:16 p.m.
  • (edited)

Это какая-то жесть. Вместо 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
    • March 17, 2018, 5:21 p.m.

    Добрый день!
    У модели и маппера изначально вообще нет родителя. Вы же не передаёте указатель на родителя, когда выделяете память в куче. А то, что окно имеет доступ к ним, так это лишь благодаря тому, что Вы зарегистрировали их в качестве контекста в 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 вместо указателя.

              Comments

              Only authorized users can post comments.
              Please, Log in or Sign up
              d
              • dsfs
              • April 26, 2024, 1:56 a.m.

              C ++ - Test 004. Pointers, Arrays and Loops

              • Result:80points,
              • Rating points4
              d
              • dsfs
              • April 26, 2024, 1:45 a.m.

              C++ - Test 002. Constants

              • Result:50points,
              • Rating points-4
              d
              • dsfs
              • April 26, 2024, 1:35 a.m.

              C++ - Test 001. The first program and data types

              • Result:73points,
              • Rating points1
              Last comments
              k
              kmssrFeb. 8, 2024, 3:43 p.m.
              Qt Linux - Lesson 001. Autorun Qt application under Linux как сделать автозапуск для флэтпака, который не даёт создавать файлы в ~/.config - вот это вопрос ))
              Qt WinAPI - Lesson 007. Working with ICMP Ping in Qt Без строки #include <QRegularExpressionValidator> в заголовочном файле не работает валидатор.
              EVA
              EVADec. 25, 2023, 7:30 a.m.
              Boost - static linking in CMake project under Windows Ошибка LNK1104 часто возникает, когда компоновщик не может найти или открыть файл библиотеки. В вашем случае, это файл libboost_locale-vc142-mt-gd-x64-1_74.lib из библиотеки Boost для C+…
              J
              JonnyJoDec. 25, 2023, 5:38 a.m.
              Boost - static linking in CMake project under Windows Сделал всё по-как у вас, но выдаёт ошибку [build] LINK : fatal error LNK1104: не удается открыть файл "libboost_locale-vc142-mt-gd-x64-1_74.lib" Хоть убей, не могу понять в чём дел…
              G
              GvozdikDec. 18, 2023, 6:01 p.m.
              Qt/C++ - Lesson 056. Connecting the Boost library in Qt for MinGW and MSVC compilers Для решения твой проблемы добавь в файл .pro строчку "LIBS += -lws2_32" она решит проблему , лично мне помогло.
              Now discuss on the forum
              G
              GarApril 22, 2024, 2:46 a.m.
              Clipboard Как скопировать окно целиком в clipb?
              DA
              Dr Gangil AcademicsApril 20, 2024, 4:45 a.m.
              Unlock Your Aesthetic Potential: Explore MSC in Facial Aesthetics and Cosmetology in India Embark on a transformative journey with an msc in facial aesthetics and cosmetology in india . Delve into the intricate world of beauty and rejuvenation, guided by expert faculty and …
              a
              a_vlasovApril 14, 2024, 3:41 a.m.
              Мобильное приложение на C++Qt и бэкенд к нему на Django Rest Framework Евгений, добрый день! Такой вопрос. Верно ли следующее утверждение: Любое Android-приложение, написанное на Java/Kotlin чисто теоретически (пусть и с большими трудностями) можно написать и на C+…
              Павел Дорофеев
              Павел ДорофеевApril 13, 2024, 11:35 p.m.
              QTableWidget с 2 заголовками Вот тут есть кастомный QTableView с многорядностью проект поддерживается, обращайтесь
              f
              fastrexApril 4, 2024, 1:47 a.m.
              Вернуть старое поведение QComboBox, не менять индекс при resetModel Добрый день! У нас много проектов в которых используется QComboBox, в версии 5.5.1, когда модель испускает сигнал resetModel, currentIndex не менялся. В версии 5.15 при resetModel происходит try…

              Follow us in social networks