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

QListWidgetItems causing memory overhead



  • I'm populating a Custom List Widget with over 600 items using:

    listWidget->addCustomItem(new CustomListWidgetItem(fileList.at(j), QIcon(":/icons/music.png")));
    

    Which was taking insane amount of memory ram. Does anyone knows why?


  • Lifetime Qt Champion

    Hi
    600 do not sound like much.
    Do you use setItemWidget or anything heavy ?
    What did you add to CustomListWidgetItem vs the normal Item ?

    What is "insane amount of memory ram" ?



  • @mrjj Hi, explaining a little bit more.

    1.- The items are custom just because i was adding extra info via QFileInfoList
    2.- The memory ram was taking about 1.5 GB of ram for my little application to run, when i changed that line of code to:

    QIcon icon(":/icons/music.png");
    listWidget->addCustomItem(new CustomListWidgetItem(fileList.at(j), icon));
    

    The memory usage was reduced to just 40 - 50 MB. Please take a look at this as i wanted my code to be reviewed as well to spot my weaknesses in code and design process but i'm not sure if a qualified programmer will take some time to do it.


  • Lifetime Qt Champion

    Hi
    Wait what, moving the icon to its own line, reduced it by HUGE factor ?

    Do you have that code anywhere as zip including the qres file and .pro file so
    i could run it and see if same happens here.

    It seems very odd with such mem use considering its some text and an icon.
    I assume QFileInfoList is not loaded with tons and tons of files ?


  • Qt Champions 2019

    How big is your music.png? (not kb, image size is important)
    When you create a new icon every time it definitely needs more memory than using the same icon every time. But this should not go into Gb when the icon is small.

    btw: your dtor looks really weird:

    CustomListWidgetItem::~CustomListWidgetItem(){
        delete &fileInfo;
    }
    

    This will crash for sure...
    And in CustomListWidget::addCustomItem() you're creating a QListWidgetItem for no good reason.



  • @mrjj Ok you can try the code from here



  • @Christian-Ehrlicher Can you tell me exactly why? How would you write those functions? What guidelines should i use? as i point out i'm trying to code the C++ & Qt way i'm just not quite there yet.


  • Lifetime Qt Champion

    Hi
    Tried the app. Used 560 MB here.
    Considering all the MP3 fils it seems not excessive.

    The reason
    delete &fileInfo;
    is wrong is that its not created as
    QFileInfo * fileInfo = new QFileInfo();
    but as
    QFileInfo fileInfo;
    Which means its just a normal member and will be deleted by with the class automatically.

    Then there is ( as @Christian-Ehrlicher mentions )

    void CustomListWidget::addCustomItem(CustomListWidgetItem *customItem){
        list.push_back(customItem);
        qDebug() << "Custom Item Added: " << list.size() << endl;
        QListWidgetItem *item = new QListWidgetItem(this);
        item->setText(customItem->text());
        item->setIcon(customItem->icon());
    }
    

    Since item is not inserted into anything it seems unused ?



  • @mrjj said in QListWidgetItems causing memory overhead:

    QListWidgetItem
    I think this constructor adds the item if the parent is passed in
    From the docs
    "This constructor inserts the item into the model of the parent that is passed to the constructor. If the model is sorted then the behavior of the insert is undetermined since the model will call the '<' operator method on the item which, at this point, is not yet constructed. To avoid the undetermined behavior, we recommend not to specify the parent and use QListWidget::insertItem() instead."
    So that might not be a problem unless there is something wrong with the parent? You could pass a null ptr to the parent and use insertItem to see if it makes a difference.



  • @mrjj Tried to rewrite:

    QIcon icon(":/icons/music.png");
    listWidget->addCustomItem(new CustomListWidgetItem(fileList.at(j), icon));
    

    To see what happens? Because the more scenes the more ram it consumes.

    And yes the item is being added here

    QListWidgetItem *item = new QListWidgetItem(this);
    

  • Qt Champions 2017

    @mrjj said in QListWidgetItems causing memory overhead:

    Wait what, moving the icon to its own line, reduced it by HUGE factor ?

    @onimusha said in QListWidgetItems causing memory overhead:

    @Christian-Ehrlicher Can you tell me exactly why? How would you write those functions? What guidelines should i use? as i point out i'm trying to code the C++ & Qt way i'm just not quite there yet.

    Due to implicit sharing this is quite an expected result. In your case you're loading 600 times the same image and creating 600 separate objects holding the same data. In the latter case, you load and have the data once and get 599 objects just pointing to the same data. That by itself is a reduction of 1.5 in thousand for the memory footprint, not counting all the overhead of the items themselves obviously. One usually uses the model-view architecture for such medium-to-large lists.


  • Qt Champions 2019

    You're still creating two QListWidgetItems for one entry:

    • listWidget->addCustomItem(new CustomListWidgetItem(...))
    • QListWidgetItem *item = new QListWidgetItem(this);

    The second one is absolutely useless - just use addItem() for the first one. Then you also don't need the other stuff in emitCustomItem() and startDrag which will not work as soon as there are two items with the same baseName() ...


  • Lifetime Qt Champion

    @kshegunov
    Ah, yes. Will create a temp object on each call , and have no way of sharing
    first instance. Just realized i have done that a few places.. (doh)



  • @kshegunov I see now, that answers my question. Thanks.


Log in to reply