Виталий Антипов
Виталий Антипов17 марта 2018 г. 23: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
Стабильный хостинг, на котором располагается социальная сеть EVILEG. Для проектов на Django рекомендуем VDS хостинг.

Вам это нравится? Поделитесь в социальных сетях!

6
Виталий Антипов
  • 18 марта 2018 г. 3:16
  • (ред.)

Это какая-то жесть. Вместо 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
    • 18 марта 2018 г. 3:21

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


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

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

        Виталий Антипов
        • 18 марта 2018 г. 4:13

        Qt 5.10.1.

          Виталий Антипов
          • 18 марта 2018 г. 6:39

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

          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.
          В релиз сборке приложение не падает.
          Все-таки нашел источник проблемы. Я в интерфейс накидал много огромных моделей данных, но если их заранее уменьшить то проблем нет.
          И все-таки хотелось бы вернуться к первому вопросу. Если модель и маппер не имеют родителя, то какой смысл им выделять динамическую память? ведь после вызова они будут жить до конца жизни программы и весь смысл в куче пропадает.
            Evgenii Legotckoi
            • 18 марта 2018 г. 18:46

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

              Комментарии

              Только авторизованные пользователи могут публиковать комментарии.
              Пожалуйста, авторизуйтесь или зарегистрируйтесь
              Ua

              Qt - Тест 001. Сигналы и слоты

              • Результат:84баллов,
              • Очки рейтинга4
              Ua

              Qt - Тест 001. Сигналы и слоты

              • Результат:42баллов,
              • Очки рейтинга-8
              ОК

              Qt - Тест 001. Сигналы и слоты

              • Результат:47баллов,
              • Очки рейтинга-6
              Последние комментарии
              ИМ
              Игорь Максимов22 ноября 2024 г. 21:51
              Django - Урок 017. Кастомизированная страница авторизации на Django Добрый вечер Евгений! Я сделал себе авторизацию аналогичную вашей, все работает, кроме возврата к предидущей странице. Редеректит всегда на главную, хотя в логах сервера вижу запросы на правильн…
              Evgenii Legotckoi
              Evgenii Legotckoi31 октября 2024 г. 23:37
              Django - Урок 064. Как написать расширение для Python Markdown Добрый день. Да, можно. Либо через такие же плагины, либо с постобработкой через python библиотеку Beautiful Soup
              A
              ALO1ZE19 октября 2024 г. 17:19
              Читалка fb3-файлов на Qt Creator Подскажите как это запустить? Я не шарю в программировании и кодинге. Скачал и установаил Qt, но куча ошибок выдается и не запустить. А очень надо fb3 переконвертировать в html
              ИМ
              Игорь Максимов5 октября 2024 г. 16:51
              Django - Урок 064. Как написать расширение для Python Markdown Приветствую Евгений! У меня вопрос. Можно ли вставлять свои классы в разметку редактора markdown? Допустим имея стандартную разметку: <ul> <li></li> <li></l…
              d
              dblas55 июля 2024 г. 20:02
              QML - Урок 016. База данных SQLite и работа с ней в QML Qt Здравствуйте, возникает такая проблема (я новичок): ApplicationWindow неизвестный элемент. (М300) для TextField и Button аналогично. Могу предположить, что из-за более новой верси…
              Сейчас обсуждают на форуме
              f
              firstlunoxod15 февраля 2025 г. 13:46
              Рисование на QGraphicsScene при зажатой кнопке мыши Подскажите, пожалуйста! Как данный класс можно дополнить, чтобы созданные объекты можно было перемещать мышкой по сцене?
              Дмитрий
              Дмитрий3 февраля 2025 г. 16:24
              Создание deb-пакета. Как создать ярлык на рабочем столе после установки собственного deb-пакета? Всем привет. Сделал свой deb-пакет с программой. Всё устанавливается и работает. Ставлю по пути /usr/bin/my_application. Как для пользователя при установке пакета сразу создать ярлык на раб…
              NW
              Nayo Wai30 января 2025 г. 19:22
              не запускается компьютер!!! Не запускается компьютер (точнее работает блок , но сам монитор вообще жесть)В общем я ничего с интернета не скачивала в последнее время. На компе никаких левых пр…
              n
              nkly3 января 2025 г. 12:52
              Нужно запретить перемещение только некоторых итемов, остальные перемещать можно. Вопрос решен. Узнать QModelIndex элемента на который мы перетаскиваем другой элемент, можно с помощью функции indexAt(event->position().toPoint()) представления QTreeViev вызываемой в переопр…
              M
              Marsel17 августа 2023 г. 0:26
              OAuth2.0 через VK, получение email Спасибо большое за помощь и простите за то что отнял время своей невнимательностью.

              Следите за нами в социальных сетях