当动态创建的对象具有父

时间:2017-08-09 11:17:40

标签: qt memory-management qml

我使用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)。

2 个答案:

答案 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()手动调用垃圾收集器。这将导致执行全面的收集周期,这可能需要几百到几千毫秒才能完成,因此如果可能的话应该避免这样做。

source