Results 1 to 5 of 5

Thread: QIcon has increased memory usage because pixmaps are not loaded on demand?

  1. #1
    Join Date
    Feb 2014
    Posts
    4
    Qt products
    Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default QIcon has increased memory usage because pixmaps are not loaded on demand?

    Hello,

    Im currently updating my application from Qt 5.2.1 with MinGW 4.8 to Qt 5.7 with MinGW 5.3. I am using the precompiled packages from the online installer under Windows 7. If I compile with Qt 5.7 I see a significant increase of memory consumption during runtime in the task manager from around 70 MB with Qt 5.2.1 to 380 MB with Qt 5.7. So I tried to find the reason for that behaviour.

    I found that the QComboBox method http://doc.qt.io/qt-4.8/http://doc.qt.io/qt-5/qcombobox.html#addItem-1 overload that takes a QIcon is increasing the memory usage. After testing around, I think the memory increased is caused because http://doc.qt.io/qt-4.8/http://doc.qt.io/qt-5/qicon.html#addFile creates pixmaps for every Icon Mode and Icon State and load it into memory at initialisation and not like the documentation mentioned on demand.
    Adds an image from the file with the given fileName to the icon, as a specialization for size, mode and state. The file will be loaded on demand.
    I searched the internet about this problem, but the only thing I found was https://forum.qt.io/topic/72240/qico...xmap-on-demand. That suprised me, because a increase of the memory footprint for about 300% isn't something that you miss as a developer.

    I prepared a minimal example thats shows the problem. I use PNG Files attached to the Qt resource system, but you can use files in the application directory as well.

    Qt Code:
    1. #include <QApplication>
    2. #include <QWidget>
    3. #include <QComboBox>
    4. #include <QVBoxLayout>
    5.  
    6. int main(int argc, char *argv[])
    7. {
    8. //QCoreApplication::setAttribute(Qt::AA_EnableHighDpiScaling, true);
    9. //QCoreApplication::setAttribute(Qt::AA_UseHighDpiPixmaps, false);
    10.  
    11. QApplication a(argc, argv);
    12.  
    13. bool useIcon = true;
    14. bool usePixmap = false;
    15. QWidget mainWidget;
    16. QVBoxLayout *layout = new QVBoxLayout;
    17. for(int i = 0; i < 20; ++i)
    18. {
    19. QComboBox *box = new QComboBox;
    20. box->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    21. if(useIcon)
    22. {
    23. if(usePixmap)
    24. {
    25. box->addItem(QIcon(QPixmap(":/img/about-icon.png")), QObject::tr("Box %1 - 1").arg(i));
    26. box->addItem(QIcon(QPixmap(":/img/android-add-contact.png")), QObject::tr("Box %1 - 2").arg(i));
    27. box->addItem(QIcon(QPixmap(":/img/Bug.png")), QObject::tr("Box %1 - 3").arg(i));
    28. box->addItem(QIcon(QPixmap(":/img/database-symbol-md.png")), QObject::tr("Box %1 - 4").arg(i));
    29. box->addItem(QIcon(QPixmap(":/img/Devices-printer-icon.png")), QObject::tr("Box %1 - 5").arg(i));
    30. }
    31. else
    32. {
    33. box->addItem(QIcon(":/img/about-icon.png"), QObject::tr("Box %1 - 1").arg(i));
    34. box->addItem(QIcon(":/img/android-add-contact.png"), QObject::tr("Box %1 - 2").arg(i));
    35. box->addItem(QIcon(":/img/Bug.png"), QObject::tr("Box %1 - 3").arg(i));
    36. box->addItem(QIcon(":/img/database-symbol-md.png"), QObject::tr("Box %1 - 4").arg(i));
    37. box->addItem(QIcon(":/img/Devices-printer-icon.png"), QObject::tr("Box %1 - 5").arg(i));
    38. }
    39. }
    40. else
    41. {
    42. box->addItem(QObject::tr("Box %1 - 1").arg(i));
    43. box->addItem(QObject::tr("Box %1 - 2").arg(i));
    44. box->addItem(QObject::tr("Box %1 - 3").arg(i));
    45. box->addItem(QObject::tr("Box %1 - 4").arg(i));
    46. box->addItem(QObject::tr("Box %1 - 5").arg(i));
    47. }
    48. layout->addWidget(box);
    49. }
    50. mainWidget.setLayout(layout);
    51. mainWidget.show();
    52.  
    53. return a.exec();
    54. }
    To copy to clipboard, switch view to plain text mode 

    I compiled a realease build and running this example with Qt 5.2.1 and Qt 5.7. on Windows 7. The memory consumption is measured using the windows task manager. These are the results:

    • useIcon = true, usePixmap = false:
      • Qt 5.2.1: 5740 KB
      • Qt 5.7: 46472 KB
    • useIcon = true, usePixmap = true:
      • Qt 5.2.1: 7184 KB
      • Qt 5.7: 9712 KB
    • useIcon = false:
      • Qt 5.2.1: 4636 KB
      • Qt 5.7: 8096 KB


    My question are:
    • Can you reproduce this behaviour?
    • Is there a flag that controls if the pixmaps are loaded on demand or not?
    • Is there a workaround or should I fill out a bug report?


    Thank you very much.
    ~ Markus

  2. #2
    Join Date
    Feb 2014
    Posts
    4
    Qt products
    Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: QIcon has increased memory usage because pixmaps are not loaded on demand?

    Is there anyone who can help or even reproduce this? Please let me know if I provided not enough informations.
    Im currently try to write my own QIconEngine as a workaround.

  3. #3
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,420
    Thanks
    37
    Thanked 1,545 Times in 1,495 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: QIcon has increased memory usage because pixmaps are not loaded on demand?

    Can you attach a buildable example as a ZIP archive?

    Maybe in a way that takes the two bools from commandline args the program can be quickly run through all options?

    If this is a bug that would also help the bug report as any respective developer would have a test case at hand.

    Cheers,
    _

  4. #4
    Join Date
    Feb 2014
    Posts
    4
    Qt products
    Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: QIcon has increased memory usage because pixmaps are not loaded on demand?

    Thank you very much for your response. I attaches a zip file with the buildable example. It has two boolean command line options:
    • -i or --icon : use the QIcon constructor
    • -p or --pixmap : use the QPixmap constructor

    If you set both, the QIcon constructor will be used, if you set none no icons will be loaded.

    Qt Code:
    1. #include <QApplication>
    2. #include <QWidget>
    3. #include <QLabel>
    4. #include <QComboBox>
    5. #include <QVBoxLayout>
    6. #include <QCommandLineParser>
    7. #include <QCommandLineOption>
    8.  
    9. int main(int argc, char *argv[])
    10. {
    11. QApplication a(argc, argv);
    12.  
    13. QCommandLineParser parser;
    14. parser.setApplicationDescription("A test to observe memory usage of QIcon.");
    15. parser.addHelpOption();
    16.  
    17. QCommandLineOption useIconOption(QStringList() << "i" << "icon", "Use the QIcon constructor");
    18. parser.addOption(useIconOption);
    19. QCommandLineOption usePixmapOption(QStringList() << "p" << "pixmap", "Use the QPixmap constructor");
    20. parser.addOption(usePixmapOption);
    21.  
    22. parser.process(a);
    23.  
    24. bool useIcon = parser.isSet(useIconOption);
    25. bool usePixmap = parser.isSet(usePixmapOption);
    26.  
    27. QWidget mainWidget;
    28. QVBoxLayout *layout = new QVBoxLayout;
    29. if(useIcon)
    30. {
    31. layout->addWidget(new QLabel("Using Icon Contructor"));
    32. }
    33. else if(usePixmap)
    34. {
    35. layout->addWidget(new QLabel("Using Pixmap Contructor"));
    36. }
    37.  
    38. for(int i = 0; i < 20; ++i)
    39. {
    40. QComboBox *box = new QComboBox;
    41. box->setSizePolicy(QSizePolicy::Expanding, QSizePolicy::Expanding);
    42. if(useIcon)
    43. {
    44. box->addItem(QIcon(":/img/about-icon.png"), QObject::tr("Box %1 - 1").arg(i));
    45. box->addItem(QIcon(":/img/android-add-contact.png"), QObject::tr("Box %1 - 2").arg(i));
    46. box->addItem(QIcon(":/img/Bug.png"), QObject::tr("Box %1 - 3").arg(i));
    47. box->addItem(QIcon(":/img/database-symbol-md.png"), QObject::tr("Box %1 - 4").arg(i));
    48. box->addItem(QIcon(":/img/Devices-printer-icon.png"), QObject::tr("Box %1 - 5").arg(i));
    49. }
    50. else if(usePixmap)
    51. {
    52. box->addItem(QIcon(QPixmap(":/img/about-icon.png")), QObject::tr("Box %1 - 1").arg(i));
    53. box->addItem(QIcon(QPixmap(":/img/android-add-contact.png")), QObject::tr("Box %1 - 2").arg(i));
    54. box->addItem(QIcon(QPixmap(":/img/Bug.png")), QObject::tr("Box %1 - 3").arg(i));
    55. box->addItem(QIcon(QPixmap(":/img/database-symbol-md.png")), QObject::tr("Box %1 - 4").arg(i));
    56. box->addItem(QIcon(QPixmap(":/img/Devices-printer-icon.png")), QObject::tr("Box %1 - 5").arg(i));
    57. }
    58. else
    59. {
    60. box->addItem(QObject::tr("Box %1 - 1").arg(i));
    61. box->addItem(QObject::tr("Box %1 - 2").arg(i));
    62. box->addItem(QObject::tr("Box %1 - 3").arg(i));
    63. box->addItem(QObject::tr("Box %1 - 4").arg(i));
    64. box->addItem(QObject::tr("Box %1 - 5").arg(i));
    65. }
    66. layout->addWidget(box);
    67. }
    68. mainWidget.setLayout(layout);
    69. mainWidget.show();
    70.  
    71. return a.exec();
    72. }
    To copy to clipboard, switch view to plain text mode 
    Attached Files Attached Files

  5. #5
    Join Date
    Feb 2014
    Posts
    4
    Qt products
    Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: QIcon has increased memory usage because pixmaps are not loaded on demand?


Similar Threads

  1. get cpu and memory usage
    By smemamian in forum Newbie
    Replies: 2
    Last Post: 7th October 2013, 17:11
  2. Replies: 4
    Last Post: 16th April 2011, 11:19
  3. Displaying pixmaps and memory leak ??
    By tonytony in forum Qt Programming
    Replies: 7
    Last Post: 29th June 2010, 14:12
  4. CPU and Memory Usage
    By philwinder in forum Qt Programming
    Replies: 16
    Last Post: 17th May 2008, 23:25
  5. QString memory usage
    By jogeshwarakundi in forum Newbie
    Replies: 1
    Last Post: 13th December 2007, 07:48

Tags for this Thread

Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  
Digia, Qt and their respective logos are trademarks of Digia Plc in Finland and/or other countries worldwide.