My qml application eventually uses up all the memory in my embedded device.
The application is a media player with about 17,000 different items in its library. About half have an image related to it. I use list views and grid views to display the content on different screens. After looking at pretty much every item the memory usage of the qml application is about 250M. It seems like the images are not being unloaded. Is there a way, in Qt Quick 1.0, to force an image to be unloaded or deallocated?
It seems like the image's should get clean up by the garbage collector, but they're not. I create most of the images in delegates; which should get destroyed when they are scrolled out of the viewing bounds.
If anyone has some suggestion on how to manage the memory usage it would be greatly appreciated.
Good question! I'm sorry, there seems no direct way to do this, but how about make a model class yourself. If you have over than 17,000 items in your application. You can load them(maybe just 20 items in a view) just when they're really use in your model(just display in your view). I'm not sure if the default/native model in QML has this kind of controlling, but you still can try it yourself :-)
Have you tried using the QML Image sourceSize property to at least reduce memory usage ?
Memory usage in embedded devices is my main source of troubles too, my guess is that images are cached and for some reason in embedded devices the cache is not purged quick enough or the garbage collector thinks the cached images are in use for some reason.
There should be an image cache in QML:
Are you sure that the leak is not somewhere on your C++ side (Models, etc.?)
Roberto Raggi instantiates in his excellent "presentation":http://qt.nokia.com/developer/learning/online/talks/developerdays2010/tech-talks/qt-quick-for-c-developers 1 Million items in ListView. Qt Quick is able to handle large datasets.
I have tried sourceSize. I felt like it hurt performance, and since I use the same image with different sizes it didn't really seem like a good solution. That is because every time I used a different size it would load a new image.
I actually don't put all the items in one model. I created a QML Sql Plugin using the QSqlQueryModel. I have 4 models that update based on what category, album, genre the user chooses. I believe the largest query results in about 280 items.
I think i'm going to try something and see if it helps:
When I receive the Component.onDestruction signal in an Image element I'm going to set the source to an empty string. Maybe that will change the reference count on the image. I hope this is not the case because the deconstruction of the image it self should update the reference count, but I guess I have nothing to loose.
When it comes to loading images you can accelerate things a lot when images are loaded asynchronously. Simply set the property Image::asynchronous
@bundickt: are you using lots of string concatenations in your QML code ?
I guess that besides images you perform lots of string operations on title, author, etc.
In another application i'm working on i've noticed that using
myProperty = "aaaa" + "bbbb" + "cccc"
causes memory leaks (or at least it makes garbage collection harder), while
myProperty = ["aaaa" + "bbbb" + "cccc"].join()
seems to work a lot better (and does not produce the "memory leaks" that happens using simple string concatenation).
Thanks L.MCH I will try that.
FYI, setting the source to empty string on deconstruction did help.