我使用Component.createObject()
方法动态创建对象。之后,我使用destroy()
方法删除对象
如果我在没有父参数的情况下调用方法Component.createObject(null)
(使用null),那么destroy()
方法将释放内存。如果我用一些parent
调用该方法,那么destroy()
方法不会释放大量内存。创建大量对象时,这会导致超出Windows操作系统中每个进程的允许内存量,从而导致应用程序崩溃。
重现问题的代码:
main.qml
import QtQuick 2.8
Item {
visible: true
width: 640
height: 480
Scene {
id: scene
anchors.fill: parent
}
}
Scene.qml
import QtQuick 2.8
Item {
id: scene
Component.onCompleted: {
var tileComponent = Qt.createComponent("Tile.qml");
for (var i = 0; i < 200000; ++i) {
var tile = tileComponent.createObject(scene);
// var tile = tileComponent.createObject(null); // this works well, but I need a parent
tile.destroy();
}
}
}
Tile.qml
import QtQuick 2.8
Rectangle {
width: 100
height: 100
color: "orange"
}
父级变体在destroy()
之后使用40 MB内存,没有父级 - 12 MB。如果我继续创建和销毁这些对象,则使用的内存会继续增长
如何动态创建和销毁很多父对象,避免内存问题?
我在Windows 7 x64上测试了Qt 5.9.1(MinGW 5.3.0编译器)和Qt 5.8.0(MSVC 2015)。
答案 0 :(得分:1)
QML并不喜欢释放内存,但是你也可以通过调用gc()
来强制它,并且通常有利于按顺序调用它,它会在第3次调用之前继续挤压额外的内存。 / p>
从好的方面来说,如果您创建更多对象而不是分配更多内存,则会重复使用已用内存。
总而言之,QML是一种记忆力。即使从QML创建简单,不可见的QObject
也有significant overhead。所以我建议,如果可能的话,使用一些C ++驱动的模型而不是成千上万的QML对象只是坐在内存中,延迟加载,按需加载 - 这样的技术将为你的内存使用创造奇迹。
答案 1 :(得分:0)
这种行为对Qt来说是正常的。你不需要做任何事情。如果你继续测试,你会在某个时候看到内存使用量停止增长。
我建议不要使用kmeans = tf.contrib.learn.KMeansClustering(num_clusters = n_clusters, relative_tolerance=0.0001)
,因为它确实无济于事。它迫使Qt做一些它会在需要时自动完成的事情。
可以通过在JavaScript中调用gc()手动调用垃圾收集器。这将导致执行全面的收集周期,这可能需要几百到几千毫秒才能完成,因此如果可能的话应该避免这样做。