Important: Please read the Qt Code of Conduct - https://forum.qt.io/topic/113070/qt-code-of-conduct

Saving memory by freeing off-screen QListView items?



  • Hi, I'm making an image management tool that uses a QListView full of icons to preview images. These icons are heavily scaled down versions of the actual images, generates the first time they need to be shown, and load from my database very quickly when needed.

    As I scroll through my QListView (backed by a QSqlTableModel), the memory usage of my application rapidly increases. After about 1,000 images my application is using several gigabytes of memory. I believe this is because either the QListView is not freeing off-screen QIcons, or the underlying QSqlTableModel has no mechanism to free rows that have already been retrieved. Is there some way I could force whichever one is causing the issue to free memory related to images not currently onscreen?


  • Qt Champions 2019

    There is nothing like a QListView item. It's all in the model.
    Don't save the images in memory in full resolution but scale them down.



  • @Christian-Ehrlicher I'm keeping everything heavily scaled down, actually. I guess then it becomes a matter of making my QSqlTableModel free old records.


  • Qt Champions 2019

    @tague said in Saving memory by freeing off-screen QListView items?:

    I guess then it becomes a matter of making my QSqlTableModel free old records.

    How much rows do you have? QSqlTableModel can't 'free' any data.
    Do you derive from QSqlTableModel and fetch the image by your own so you can scale it down? Otherwise there will be the big image in memory.



  • @Christian-Ehrlicher said in Saving memory by freeing off-screen QListView items?:

    How much rows do you have? QSqlTableModel can't 'free' any data.
    Do you derive from QSqlTableModel and fetch the image by your own so you can scale it down? Otherwise there will be the big image in memory.

    I don't do that at the moment, but I am working on creating a similar model class that doesn't retain row information, but instead only SELECTs it when data is invoked.


  • Lifetime Qt Champion

    Hi,

    Beware with that, data is called frequently as the model provides lots of information. Beside what @Christian-Ehrlicher already suggested, you might also want to use a windowing mechanism that fetches a fixed amount of row data and then add/remove new rows depending on the scrolling of the view.



  • @SGaist Thanks for the heads up. Is there a way to do that without my model being heavily dependent on my particular QListView? So far, I've made a generic CachingTableModel that uses a QCache to keep the last few hundred items cached, and which has an overridable virtual method that converts a table row into the appropriate QVariant data representation. It's actually been rather efficient (about 100MB of memory used at its peak) and on my device (with an SSD, reading from an SQLite table of around 8,000 entries) reads new entries with no trouble at all.


  • Qt Champions 2019

    Again - what do you save in that model when there are only 'a few hundreds items' in there and you need 100MB?



  • @Christian-Ehrlicher It caches entries that could have fairly high resolution images in them. 100MB consumed is quite reasonable for my particular use case. I've solved my problem my creating a general-purpose list model class which does not retain too many recent items in memory, and then implementing an application-specific subclass that will automatically produce small, low-resolution thumbnails and save them to a separate table to allow for faster loading later on.



  • This post is deleted!