即使我没有动态创建任何qml对象,内存泄漏?

时间:2015-08-29 02:19:23

标签: qt qml

我想创建一个工具栏,当悬停时它会旋转和展开。但内存泄漏非常严重,可能会消耗任意RAM,初始内存使用量约为20MB,1000次动画后达到300mb。我只使用基本组件,如ListView,Rectangle和MouseArea。这是完整的源代码。我是qml的新手。任何建议将不胜感激,谢谢。

//MyListView.qml
//The ListView will expand when activated.
ListView{
id:root
orientation: ListView.Horizontal
property alias list: listModel

width: calcWidth()

signal optionSelected(string option)

function enableItems(big){
    for(var i in root.contentItem.children){
        var child = root.contentItem.children[i]
        if(child.objectName!=="delegate") continue

        if(big){ child.state="big" }
        else child.state=""
    }
}

function calcWidth(){
    var w = 0
    for(var i in root.contentItem.children) {
        var child = root.contentItem.children[i]
        if(child.objectName==="delegate"){
            w+=child.width
        }
    }
    return w
}

model: ListModel{
    id:listModel
}

delegate: Rectangle{
    id: rect
    objectName: "delegate"
    height: parent.height
    width: 0
    color:"transparent"
    border.color:"grey"; border.width:1; radius: 5
    rotation: width/root.height * 360

    states:State{
        name: "big"
        PropertyChanges{
            target: rect;  width: root.height
        }
    }

    transitions: Transition {
        from: "*"
        to: "big"
        reversible: true
        NumberAnimation{
            properties: "width";easing.type: Easing.OutQuad; duration: 400
        }
    }

    Image{
        anchors.fill: parent
        source: imgSrc
    }

    MouseArea{
        anchors.fill: parent
        hoverEnabled: true
        onEntered: enableItems(true)
        onExited: enableItems(false)
        onClicked: root.optionSelected(option)
    }
}
}

//MyRow.qml
Row{
id:root
width: mainImg.width + listView.width
property alias list: listView.list
property alias mainImg: mainImg.source

signal optionSelected(string option)

Image{
    id: mainImg;  height: parent.height;  width: parent.height

    MouseArea{
        anchors.fill: parent
        hoverEnabled: true
        onEntered: listView.enableItems(true)
        onExited: listView.enableItems(false)
    }
}

MyListView{
    id: listView
    height: root.height
    onOptionSelected: root.optionSelected(option)
}
//test memory usage
Timer{
    id: timer
    running: true; interval: 400; repeat: true
    property real times:0
    property bool big :false
    onTriggered: {
        times ++
        big = !big
        listView.enableItems(big)
        console.log(big+""+times)
        if(times>500){
            timer.running = false
            gc()
        }
    }
}
}

//main.qml
Rectangle {
width: 360
height: 360

MyRow{
    height: 128
    mainImg: "qrc:/4.png"
    onOptionSelected: console.log(option)

    Component.onCompleted: {
        list.append({imgSrc:"qrc:/1.png",option:"111"})
        list.append({imgSrc:"qrc:/2.png",option:"222"})
        list.append({imgSrc:"qrc:/3.png",option:"333"})
    }
}
}

Edit1:我使用的是Qt 5.5.0 + Linux Mint 17.1 + KDE。切换到Qt 5.4.2 + Windows 10后,一切正常。

1 个答案:

答案 0 :(得分:1)

我不相信你确实已经建立了内存泄漏。 QML引擎将缓存,看起来内存使用量上升20-30 mb是一件很常见的事情。

  

但内存泄漏严重

没有任何具体的数字,人们只能猜出你的意思。内存使用量是否超过30 MB并继续上升?它达到了100吗?还是更多?

请记住JS是垃圾收集的,根据我自己的经验收集远非逻辑,至少在QML中。有时我会在应用程序生命周期中一直使用非引用对象,有时我会在QML因某种原因决定删除它们时得到仍在使用的对象,结果是段错误和崩溃。

顺便说一句,您可以使用gc()强制进行垃圾回收,看看是否有任何好处。

正如在this similar post中已经确定的那样,“正常”的行为是记忆会上升到某一点然后稳定下来,我怀疑这种情况也会发生在你的情况下。您应该进一步调查并发布具体数字,并在必要时发布错误报告。

编辑:我在Qt 5.42上测试了你的示例代码,内存使用量很快就达到了47.068 MB,并且在500个动画之后它仍然存在,根据任务管理器还没有向上移动一个kb,它实际上已经下降了如果动画停止则很少,如果恢复则返回47.068 MB。

使用Qt 5.5,它稳定在51.672 MB

如果您运行的字面上相同的代码,您的Qt版本可能有一个错误。