Results 1 to 16 of 16

Thread: Big memory problem

  1. #1
    Join Date
    May 2013
    Posts
    321
    Thanks
    9
    Thanked 8 Times in 8 Posts
    Qt products
    Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Exclamation Big memory problem

    Hi,
    I recently saw the memory of my application grows and never decrease.
    It's apparently because when I spawn a QMenu and QDialog I use new operator and never delete them.
    I thought close a window deleted them but I was wrong, it's why the DeleteOnClose attribute is there.
    But, I saw QMessageBox using static function delete after it's closed, so I guess it has the attribute.
    Is QMessageBox the only class which set DeleteOnClose attribute and all other has to be set manually ?
    Does QMenu contains the flag by default or it has to be set manually ?
    Thanks

  2. #2
    Join Date
    Sep 2015
    Posts
    12
    Thanked 3 Times in 3 Posts
    Qt products
    Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Big memory problem

    You should not need to create new instances of QMenu every time you use it. For the main menu it is put into the constructor of the parent. If you use QAction in the menus you really don't need to deal with it too much (depends on your goal of course). If you have a context menu you can create it on the stack and not on the heap. The Qt documentation has some good examples: http://doc.qt.io/qt-5/qtwidgets-main...s-example.html

    For dialogs you can use a combination of methods. They can be on the stack if appropriate (popup message-box type of dialog) or you can create an instance of a dialog and attach it to the parent class (use 'new' in the constructor). If you are constantly creating a new instanace of a dialog then you need to find a way to delete it or you will exhaust memory sooner or later. I have not seen a need to do this yet.

    My personal preference for dialogs is to create them on the heap (using operator new) but only on first use. The parent widget will be contructed faster and the resources required by the dialog will only be used if the dialog is actually created. You only create one instance of the dialog so some sort of 'Reset' function is required to ensure it is at a state suitable for use (does not display previous data). This applies to both modal and modeless dialogs.

    Qt Code:
    1. // Constructor
    2. d_my_dialog = 0; // pointer to instance of my dialog
    3.  
    4. // inside some function that uses dialog
    5. if(!d_my_dialog)
    6. {
    7. d_my_dialog = new TMyDialog(this); // this open happens on first use
    8. }
    9.  
    10. d_my_dialog->Reset(); // reset the dialog to a state that is suitable (repeated use)
    11.  
    12. if(QDialog::Accepted == d_my_dialog->exec())
    13. {
    14. // do something with dialog data or whatever
    15. }
    To copy to clipboard, switch view to plain text mode 

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

    Default Re: Big memory problem

    Quote Originally Posted by Alundra View Post
    But, I saw QMessageBox using static function delete after it's closed, so I guess it has the attribute.
    Some of the static functions set the attribute, some just use a stack allocated messagebox instance.

    Quote Originally Posted by Alundra View Post
    Is QMessageBox the only class which set DeleteOnClose attribute and all other has to be set manually ?
    No widget sets that attribute by default, QMessageBox certainly doesn't.

    Cheers,
    _

  4. #4
    Join Date
    May 2013
    Posts
    321
    Thanks
    9
    Thanked 8 Times in 8 Posts
    Qt products
    Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Big memory problem

    Maybe have a pool of dialog/widget can avoid some allocation and speed up things, can be a good change.
    Is it better to use that attribute or connect the close to deleteLater() ?
    Does it end to the same ?

  5. #5
    Join Date
    Sep 2015
    Posts
    12
    Thanked 3 Times in 3 Posts
    Qt products
    Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Big memory problem

    Do you have any sample code (pseudo code) for what you are doing? Something that shows a reason to create a 'new' dialog each time it is used?

    When you create a dialog and provide it a parent widget in the constructor it will be deleted when the parent is deleted. Options like 'Delete On Close' work if you must go this route. You can test this by simply monitoring the constructor/destructor calls and verify the memory is released.

    I have never had a reason to do this nor can I picture something that requires this approach.

    Note: Using a pool of dialog/widget is the same idea of creating one instance and reusing it as needed. I assume an instance will be requested, used, then returned (which may or may not necessarily result in a new instance being created the next time an instance is requested).

  6. #6
    Join Date
    May 2013
    Posts
    321
    Thanks
    9
    Thanked 8 Times in 8 Posts
    Qt products
    Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Big memory problem

    For example, I have a color picker which is a dialog to control color of one property, I instance using new and I exec.
    I also have a custom file browser which are dialog, it's used to show only one folder.
    I have multiple QMainWindow tabbed in one window which can be closed too.
    Surely the color picker can be reused to avoid to instance a new each time.
    Each sub window has to be deleted when closed.

  7. #7
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Big memory problem

    Surely the color picker can be reused to avoid to instance a new each time.
    The cost to construct a simple dialog is almost zero. The user will spend far more time using the dialog than it takes to create it. I think you misunderstand the point here - most of the time you should not use "new" to create a dialog on the heap, you should simply create it on the stack:

    Qt Code:
    1. void MyMainWindow::onPickColor()
    2. {
    3. MyColorPickerDlg dlg( this );
    4. dlg.setLastChosenColor( mLastColor ); // for example
    5. if ( QDialog::Accepted == dlg.exec() )
    6. {
    7. mLastColor = dlg.chosenColor();
    8. }
    9. }
    To copy to clipboard, switch view to plain text mode 

    The dialog instance is created on the stack and will automatically be destroyed when the onPickColor() method ends.

    You could do the same thing with QMenu, but as another poster said, it is easier to create them during construction as members of your window class, and use the member pointers when you need them. They are created with "new" only once (during construction) and are destroyed when the program exits.

  8. #8
    Join Date
    May 2013
    Posts
    321
    Thanks
    9
    Thanked 8 Times in 8 Posts
    Qt products
    Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Big memory problem

    You right about the stack, lifetime of the object is solved, no attribute needed for dialogs.
    For QMenu, I checked and I was wrong all QMenu is created on the stack, only QMenu* found are from menubar.
    All other QMenu is created on the stack without parent, I don't know if it's an error to not set a parent there, the result is correct visually.
    I saw here "this" is used as parent of QMenu in context menu function : http://doc.qt.io/qt-5/qtwidgets-main...s-example.html
    Maybe it's an error to not set a parent and cause again memory leaks ?
    But for sub-window, the attribute is surely needed to delete on close.
    Last edited by Alundra; 23rd September 2015 at 01:03.

  9. #9
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Big memory problem

    But for sub-window, the attribute is surely needed to delete on close.
    You mean a child window, correct? A child window will be deleted when its parent is deleted; there is no need to set the delete on close flag if you create a child window on the heap with a non-NULL parent.

    It is usually better to use hide() and show() instead of creating, deleting, and then re-creating windows. Make the child window in the parent window constructor and save the pointer. When you want to make the window visible, call pointer->show(). To make it invisible, call pointer->hide(). If you need to reset the child window to the same state as it was when it was first constructed, move that initialization code from the constructor into the showEvent().

  10. #10
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Big memory problem

    Quote Originally Posted by Alundra View Post
    Maybe it's an error to not set a parent and cause again memory leaks ?
    An object on the stack is deleted by code generated by the C++ compiler.
    And the compiler will generate that code no matter which type that is or what the programmer passed to the type's constructor.

    Quote Originally Posted by Alundra View Post
    But for sub-window, the attribute is surely needed to delete on close.
    If it has been allocated on the heap and you want to do delete on close, then yes. This is the whole purpose of this flag.

    Cheers,
    _

  11. #11
    Join Date
    May 2013
    Posts
    321
    Thanks
    9
    Thanked 8 Times in 8 Posts
    Qt products
    Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Big memory problem

    Quote Originally Posted by anda_skoa View Post
    An object on the stack is deleted by code generated by the C++ compiler.
    And the compiler will generate that code no matter which type that is or what the programmer passed to the type's constructor.
    I thought things inside the QMenu was created and since no parent was set it could cause memory leaks, good thing it doesn't happen on this case.
    Quote Originally Posted by d_stranz's View Post
    It is usually better to use hide() and show() instead of creating, deleting, and then re-creating windows. Make the child window in the parent window constructor and save the pointer. When you want to make the window visible, call pointer->show(). To make it invisible, call pointer->hide(). If you need to reset the child window to the same state as it was when it was first constructed, move that initialization code from the constructor into the showEvent().
    I understand that point, but on my case it should not stay created because I open a sub-window each time I click on one file in a file browser and then it's tabbed on the main editor, which gives lot of memory used if never deleted when not used, surely the flag is needed on this case.

  12. #12
    Join Date
    Jan 2008
    Location
    Alameda, CA, USA
    Posts
    5,230
    Thanks
    302
    Thanked 864 Times in 851 Posts
    Qt products
    Qt5
    Platforms
    Windows

    Default Re: Big memory problem

    I understand that point, but on my case it should not stay created because I open a sub-window each time I click on one file in a file browser and then it's tabbed on the main editor, which gives lot of memory used if never deleted when not used, surely the flag is needed on this case.
    Then you can either use the delete on close flag, or you can call deleteLater() using the sub-window pointer during the closeEvent(). Both of these methods have the same effect. Just be sure you do not try to use the sub-window pointer after that.

  13. #13
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Big memory problem

    Quote Originally Posted by Alundra View Post
    I thought things inside the QMenu was created and since no parent was set it could cause memory leaks, good thing it doesn't happen on this case.
    What do you mean with "inside the QMenu".
    Anything that QMenu does internally is the concern of QMenu.
    But you mean actions added to the QMenu, then you need to delete those, a menu does not own the actions.

    Cheers,
    _

  14. #14
    Join Date
    May 2013
    Posts
    321
    Thanks
    9
    Thanked 8 Times in 8 Posts
    Qt products
    Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Big memory problem

    I add action using addAction of the QMenu class which takes a string as input, is it deleted correctly on this case ?
    For menubar, I create QAction on the heap and use "this" as parent then I add this action in the menu created from menubar.

  15. #15
    Join Date
    Jan 2006
    Location
    Graz, Austria
    Posts
    8,416
    Thanks
    37
    Thanked 1,544 Times in 1,494 Posts
    Qt products
    Qt3 Qt4 Qt5
    Platforms
    Unix/X11 Windows

    Default Re: Big memory problem

    Quote Originally Posted by Alundra View Post
    I add action using addAction of the QMenu class which takes a string as input, is it deleted correctly on this case ?
    http://doc.qt.io/qt-5/qmenu.html#addAction

    Quote Originally Posted by Alundra View Post
    For menubar, I create QAction on the heap and use "this" as parent then I add this action in the menu created from menubar.
    QObject with a parent.

    Cheers,
    _

  16. #16
    Join Date
    May 2013
    Posts
    321
    Thanks
    9
    Thanked 8 Times in 8 Posts
    Qt products
    Qt5
    Platforms
    MacOS X Unix/X11 Windows

    Default Re: Big memory problem

    Thanks for the link, so, for menu all sound good.
    Dialogs are now all created on the stack, so, it's solved as well.

Similar Threads

  1. QMessageBox memory problem
    By Jeffb in forum Qt Programming
    Replies: 6
    Last Post: 8th January 2012, 11:09
  2. memory allocation problem
    By marc2050 in forum Newbie
    Replies: 7
    Last Post: 23rd May 2011, 09:05
  3. Memory Leakage problem.
    By bilalsaeed in forum Qt for Embedded and Mobile
    Replies: 9
    Last Post: 13th February 2011, 19:13
  4. Qt Memory size problem ?
    By nrabara in forum Newbie
    Replies: 1
    Last Post: 29th September 2008, 15:27
  5. Virtual memory problem
    By Rahul in forum Qt Programming
    Replies: 1
    Last Post: 24th October 2007, 13:29

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.