我对QtQuick还是很陌生,并且在创建和销毁Windows时注意到了一个奇怪的问题。我们有一个大型应用程序,它具有许多不同的复杂窗口,并且我已经注意到,创建它们时,它们会使用大量的内存(几个mbs),而当我销毁它们时,内存消耗似乎并没有下降。我只想确保我正确关闭了它们,或者还有其他事情我应该做。也许重用它们?只是寻找一个对QtQuick更有经验的人做一个解释。
我发现其他人也遇到过同样的问题,但每个答案似乎都说它最终会停止,我还没有看到。我们已经在应用程序中使用Sikuli来快速打开和关闭某些窗口,最终它将占用大量内存,从而使系统崩溃。
我创建了一个迷你测试应用程序,用于演示我遇到的问题。我不确定这是内存泄漏还是只是Qt预先分配了大量内存以供使用,但似乎消耗从未停止。我运行了下面的代码,它最终爬升到2 GB的内存。我只是在使用任务管理器来监视内存使用情况,而不是其他任何工具。
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
}
}
编辑:忘记为我正在创建/销毁的窗口添加代码。