Я довольно новичок в 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
}
}
Редактировать: Забыл добавить код для окна, которое я создавал / уничтожал.