Увеличение потребления памяти с созданием и уничтожением окон qml - PullRequest
0 голосов
/ 06 июля 2018

Я довольно новичок в QtQuick и заметил странную проблему при создании и уничтожении окон. У нас есть большое приложение, которое имеет много разных сложных окон, и я заметил, что при их создании они используют большой объем памяти (несколько мегабайт), а когда я их уничтожаю, потребление памяти, похоже, совсем не уменьшается. Я просто хочу убедиться, что я закрываю их правильно, или если есть что-то еще, что я должен делать вместо этого. Может быть, повторно их использовать? Просто ищу кого-то, кто более опытен с QtQuick, чтобы дать объяснение.

Я нашел несколько сообщений от других людей, испытывающих ту же проблему, но каждый ответ, кажется, говорит о том, что он в конце концов прекратился, и я еще не видел этого. Мы использовали Sikuli в нашем приложении, чтобы быстро открывать и закрывать некоторые из наших окон, и в конечном итоге он будет использовать столько памяти, что приведет к сбою системы.

Я создал мини-приложение для тестирования, которое демонстрирует проблему, с которой я столкнулся. Я не уверен, является ли это утечкой памяти или просто Qt, выделяющей большой объем памяти заранее, чтобы использовать, но кажется, что потребление никогда не останавливается. Я запустил приведенный ниже код, и в итоге он поднялся до 2 гигабайт памяти. Я просто использовал диспетчер задач, чтобы контролировать использование памяти, а не какие-либо другие инструменты.

ObjectCreator.h

#pragma once

#include <QQmlApplicationEngine>
#include <QObject>

class ObjectCreator : public QObject
{
   public:
      explicit ObjectCreator( QQmlApplicationEngine* engine );

   public slots:
      void createAndDestroyWindow() const;

   private:
      Q_OBJECT

      QQmlApplicationEngine* engine;
};

ObjectCreator.cpp

#include <QQmlComponent>
#include <QWindow>

#include "ObjectCreator.h"

ObjectCreator::ObjectCreator( QQmlApplicationEngine* engine ) :
   engine{ engine }
{
}

void ObjectCreator::createAndDestroyWindow() const
{
   QWindow* window = nullptr;

   QQmlComponent component( engine, QUrl( QString( "qrc:///Background.qml" ) ) );
   if ( component.status() == QQmlComponent::Ready )
      window = qobject_cast< QWindow* >( component.create() );

   if ( window != nullptr )
   {
      window->close();
      window->destroy();
   }
}

main.cpp

#include <QGuiApplication>
#include <QQmlApplicationEngine>
#include <QQmlContext>

#include "ObjectCreator.h"

int main( int argc, char* argv[] )
{
   QGuiApplication app( argc, argv );
   QQmlApplicationEngine engine;

   auto objectCreator = new ObjectCreator( &engine );
   engine.rootContext()->setContextProperty( "objectCreator", objectCreator );
   engine.load( QUrl( QStringLiteral( "qrc:/main.qml" ) ) );

   return app.exec();
}

Main.qml

import QtQuick 2.7
import QtQuick.Controls 2.0

ApplicationWindow
{
   id: mainWindow

   visible: true
   width: 200
   height: 200

   Timer
   {
      interval: 50
      running: true
      repeat: true

      onTriggered: objectCreator.createAndDestroyWindow();
   }
}

Background.qml

import QtQuick 2.7
import QtQuick.Window 2.3

Window
{
   id: backgroundWindowContainer

   height: Screen.height
   width: Screen.width

   Rectangle
   {
      id: backgroundRect

      anchors.fill: parent
   }
}

Редактировать: Забыл добавить код для окна, которое я создавал / уничтожал.

...