Reputation: 5520
I want to create a toolbar, which will rotate and expand when hovered. But the memory leak is so serious that may consume arbitrary RAM, the initial memory usage is about 20MB and reaches 300mb after 1000 animations. I just uses basic components, like ListView, Rectangle and MouseArea. Here is the whole source code. I'm new to qml. Any suggestions would be appreciated, Thanks.
//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: I was using Qt 5.5.0 + Linux Mint 17.1 + KDE. Everything works fine after I switched to Qt 5.4.2 + windows 10.
Upvotes: 0
Views: 2679
Reputation: 49329
I am not convinced that you have actually established a memory leak. The QML engine will cache and it is a common thing to see memory usage rising by 20-30 mb for no apparent reason.
But the memory leak is serious
Without any concrete numbers, one can only guess what you mean by that. Does memory usage rise with more than 30 MB and keep rising? Does it reach a 100? Or more?
Keep in mind JS is garbage collected, and collection in my own experience is far from logical, at least in QML. Sometimes I get non-referenced objects living all the way through the application life cycle, sometimes I get objects which are still in use when QML decides for some reason to delete them and the result is segfaults and crashes.
BTW you can force garbage collection with gc()
and see if that does any good.
As already established in this similar post, the "normal" behavior is that memory will go up to a certain point and then stabilize, which I suspect is also happening in your case. You should investigate further and post concrete numbers, and if necessary - a bug report.
EDIT: I tested your example code on Qt 5.42, memory usage quickly reaches 47.068 MB, and after 500 animations it is still there, hasn't moved up even a single kb according to the task manager, it actually goes down a little if the animation is stopped, and returns to 47.068 MB if resumed.
With Qt 5.5 it stabilizes at 51.672 MB
In case you are running literally the same code, your Qt version may have a bug.
Upvotes: 2