Results 1 to 16 of 16

Thread: Memory Not Free immediatly after QPainter/QPainterDevice finish work

  1. #1
    Join Date
    Jul 2011
    Posts
    8
    Thanks
    1

    Default Memory Not Free immediatly after QPainter/QPainterDevice finish work

    I tested the following code, QPainter use much memory and not free even the image device is deleted, this is important for me because I need to draw polygons on thousands of images, I wish QPainter can free the memory after finish painting, is this because garbage collection or anything else?

    // step 1
    QImage* image[40000];


    // step 2
    // add about 40 M
    for (int i=0; i<size; ++i){
    image[i] = new QImage(15,15, QImage::Format_ARGB32_Premultiplied);
    }

    // step 3
    // add about 660 M
    for (int i=0; i<size; ++i){
    QPainter painter;
    painter.begin(image[i]);
    painter.end();
    }

    // step 4
    // actually not free any memory
    for (int i=0; i<size; ++i){
    delete image[i];
    }
    Last edited by wangeen; 20th July 2011 at 07:06.

  2. #2
    Join Date
    Mar 2011
    Location
    Hyderabad, India
    Posts
    1,882
    Thanks
    3
    Thanked 452 Times in 435 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows
    Wiki edits
    15

    Default Re: Memory Not Free immediatly after QPainter/QPainterDevice finish work

    what does QPainter's begin() and end() return?

  3. #3
    Join Date
    Jul 2011
    Posts
    8
    Thanks
    1

    Default Re: Memory Not Free immediatly after QPainter/QPainterDevice finish work

    return always true, it really confuse me why eat so much memory.

  4. #4
    Join Date
    Mar 2011
    Location
    Hyderabad, India
    Posts
    1,882
    Thanks
    3
    Thanked 452 Times in 435 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows
    Wiki edits
    15

    Default Re: Memory Not Free immediatly after QPainter/QPainterDevice finish work

    I don't see any problem with the way you are doing, may be something else is being missed in code.

  5. #5
    Join Date
    Jul 2011
    Posts
    8
    Thanks
    1

    Default Re: Memory Not Free immediatly after QPainter/QPainterDevice finish work

    the code works fine, I mean QPainter eat too much memory, in this case about 600 Mega, and not free immediately


    Added after 4 minutes:


    I wish I can control the lifecycle of QPainter and free memory immediatly after it is ended.
    Last edited by wangeen; 20th July 2011 at 07:50.

  6. #6
    Join Date
    Mar 2011
    Location
    Hyderabad, India
    Posts
    1,882
    Thanks
    3
    Thanked 452 Times in 435 Posts
    Qt products
    Qt4 Qt5
    Platforms
    MacOS X Unix/X11 Windows
    Wiki edits
    15

    Default Re: Memory Not Free immediatly after QPainter/QPainterDevice finish work

    Life cycle of QPainter ends as soon as the block / function it is defined returns (if defined on stack).

    Ok, I have done a small test, here I have just recreated what you said, it does not leak memory, as the size value increases the peak memory utilization increases (this should not be mistaken for memory leak), I have also attached the project files. Please compare the results with your software (vary the value of size as required)

    QPainter.zip

    Qt Code:
    1. MainWindow::MainWindow(QWidget *parent) : QMainWindow(parent)
    2. {
    3. size = 1; //40000
    4. QTimer * timer = new QTimer(this);
    5. connect(timer, SIGNAL(timeout()), this, SLOT(step1()));
    6. connect(timer, SIGNAL(timeout()), this, SLOT(step2()));
    7. connect(timer, SIGNAL(timeout()), this, SLOT(step3()));
    8. timer->start(10);
    9. }
    10.  
    11. void MainWindow::step1(void)
    12. {
    13. for(int i = 0; i < size; ++i)
    14. {
    15. image[i] = new QImage(15,15, QImage::Format_ARGB32_Premultiplied);
    16. }
    17. }
    18.  
    19. void MainWindow::step2(void)
    20. {
    21. for(int i = 0; i < size; ++i)
    22. {
    23. QPainter painter;
    24. painter.begin(image[i]);
    25. painter.end();
    26. }
    27. }
    28.  
    29. void MainWindow::step3(void)
    30. {
    31. for(int i = 0; i < size; ++i)
    32. {
    33. delete image[i];
    34. }
    35. }
    To copy to clipboard, switch view to plain text mode 

  7. #7
    Join Date
    Mar 2009
    Location
    Brisbane, Australia
    Posts
    7,729
    Thanks
    13
    Thanked 1,610 Times in 1,537 Posts
    Qt products
    Qt4 Qt5
    Platforms
    Unix/X11 Windows
    Wiki edits
    17

    Default Re: Memory Not Free immediatly after QPainter/QPainterDevice finish work

    I tested the following code, QPainter use much memory and not free even the image device is deleted, ...
    I assume you are using a blunt tool, e.g. Windows task manager, to measure the amount of memory in use by your program. Memory you have released back to the heap is often left associated with the process by the operating system unless another process is in need of it (or your process terminates). If you subsequently make heap allocations they will be granted from space already associated with your process until that space is exhausted. This is a memory fragmentation defence.

    Unless a tool like valgrind is telling you that memory is actually leaking and your process grows in an unbounded way then there is nothing to see here.

    Here is what valgrind does with Santosh Reddy's project on my Linux box:
    Qt Code:
    1. ...
    2. ==3679== HEAP SUMMARY:
    3. ==3679== in use at exit: 837,299 bytes in 8,035 blocks
    4. ==3679== total heap usage: 148,598 allocs, 140,563 frees, 6,774,554 bytes allocated
    5. ==3679==
    6. ==3679== LEAK SUMMARY:
    7. ==3679== definitely lost: 3,356 bytes in 12 blocks
    8. ==3679== indirectly lost: 10,160 bytes in 506 blocks
    9. ==3679== possibly lost: 325,614 bytes in 1,477 blocks
    10. ==3679== still reachable: 498,169 bytes in 6,040 blocks
    11. ==3679== suppressed: 0 bytes in 0 blocks
    12. ==3679== Rerun with --leak-check=full to see details of leaked memory
    13. ==3679==
    14. ==3679== For counts of detected and suppressed errors, rerun with: -v
    15. ==3679== Use --track-origins=yes to see where uninitialised values come from
    16. ==3679== ERROR SUMMARY: 667 errors from 102 contexts (suppressed: 6 from 1)
    To copy to clipboard, switch view to plain text mode 
    Very little lost.
    "We can't solve problems by using the same kind of thinking we used when we created them." -- Einstein
    If you are posting code then please use [code] [/code] tags around it - makes addressing the problem easier.

  8. #8
    Join Date
    Jul 2011
    Posts
    8
    Thanks
    1

    Default Re: Memory Not Free immediatly after QPainter/QPainterDevice finish work

    yeah, thank you very much for your replies, I tested your code, it's not memory leak I know, but the peak memory can reach 700 Mega, I think it's not reasonable for this case.


    Added after 23 minutes:


    thank you very much, I know it's not memory leak, and I tested with valgrind massif, what I can not understand is why QPainter can eat about 600 Mege memory, and what' more curious is if I deleted each image after each QPainter, the application will not reach the memory peak(700Mega).

    fine code: (most memory cost less than 50Mega)
    for (int i=0; i<size; ++i){
    QPainter painter;
    painter.begin(image[i]);
    painter.end();
    delete image[i];
    }

    not fine code:
    (most memory cost more than 700 Mega)
    // step 3
    // add about 660 M
    for (int i=0; i<size; ++i){
    QPainter painter;
    painter.begin(image[i]);
    painter.end();
    }

    // step 4
    // actually not free any memory
    for (int i=0; i<size; ++i){
    delete image[i];
    }

    Thank you very much, I know it's not memory leak, but the peak can reach 700 Mege, it's not understandable, it is too much than we anticipate.
    Attached Images Attached Images
    Last edited by wangeen; 20th July 2011 at 09:09.

  9. #9
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Memory Not Free immediatly after QPainter/QPainterDevice finish work

    Memory deallocation does not have to happen when you deallocate.
    The system may continue to hold that memory reserved for the process, even though you are freeing the memory, it is still being held for the calling process, depending on system parameters.
    So you can't be guaranteed to see linear correlation between your deallocation and the memory usage you see in the system.

    Second, please show your full code of your paintEvent(), it might be that you are causing this with a less than optimal code.
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  10. #10
    Join Date
    Jul 2011
    Posts
    8
    Thanks
    1

    Default Re: Memory Not Free immediatly after QPainter/QPainterDevice finish work

    actually I do nothing in the paintEvent(), just write this testcae, the issue I want to figure out is that whether Qt or system reserve the memory deleted, actually I guess it's more possiblely Qt did this, if so, is there anyway force Qt release the memory right now.

  11. #11
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Memory Not Free immediatly after QPainter/QPainterDevice finish work

    What is 'image'? is it a QVector?
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  12. #12
    Join Date
    Jul 2011
    Posts
    8
    Thanks
    1

    Default Re: Memory Not Free immediatly after QPainter/QPainterDevice finish work

    it's an image array.
    QImage* image[40000];

  13. #13
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Memory Not Free immediatly after QPainter/QPainterDevice finish work

    Then its not Qt who is holding the memory after you have deleted it.

    What happens if you do:
    Qt Code:
    1. //QImage* image[40000];
    2. QVector<QImage*> vecImages;
    3. //allocate the images in to the vector
    4. for (int i=0; i<vecImages.size(); ++i){
    5. QImage *pImage = vecImages.at(i);
    6. if(pImage)
    7. delete pImage;
    8. pImage = NULL;
    9. }
    10.  
    11. vecImages.clear();
    To copy to clipboard, switch view to plain text mode 
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  14. The following user says thank you to high_flyer for this useful post:

    wangeen (21st July 2011)

  15. #14
    Join Date
    Jul 2011
    Posts
    8
    Thanks
    1

    Default Re: Memory Not Free immediatly after QPainter/QPainterDevice finish work

    this do work, but is there anyway to let QPainter free memory immediately after end() called?


    Added after 52 minutes:


    I traced the Qt source code, and got the problem, actually

    when we can QPainter begin(), a engine will be created
    d->paintEngine = new QRasterPaintEngine(const_cast<QImage *>(this));

    and the problem is the engine is not free until the ~QImageData() is called, so it means that the memory will always there until the image is deleted. and when QPainter end() is called, the engine is only set not active, it still there, so if I want to use 4000 images, 4000 engines will be created, it's a big cost. maybe I need to rebuild the qt library to fill our requirement.


    Quote Originally Posted by high_flyer View Post
    Then its not Qt who is holding the memory after you have deleted it.

    What happens if you do:
    Qt Code:
    1. //QImage* image[40000];
    2. QVector<QImage*> vecImages;
    3. //allocate the images in to the vector
    4. for (int i=0; i<vecImages.size(); ++i){
    5. QImage *pImage = vecImages.at(i);
    6. if(pImage)
    7. delete pImage;
    8. pImage = NULL;
    9. }
    10.  
    11. vecImages.clear();
    To copy to clipboard, switch view to plain text mode 
    Last edited by wangeen; 21st July 2011 at 03:50.

  16. #15
    Join Date
    Jan 2006
    Location
    Munich, Germany
    Posts
    4,714
    Thanks
    21
    Thanked 418 Times in 411 Posts
    Qt products
    Qt3 Qt4 Qt5 Qt/Embedded
    Platforms
    Unix/X11 Windows

    Default Re: Memory Not Free immediatly after QPainter/QPainterDevice finish work

    The question is, do you need the 4000 images all being alive at the same time?
    If not, just delete each image after the paint operation, based on what you said, it will free the engine associated with it as well.
    If yes, then having 4000 images alive at once is going to cost you no matter what you do with the painter.
    Alternatively, you can just dynamically create and destroy the painters in the paintEvent() for each image.
    It essentially doesn't matter where you do it, it seems you can't come around creating and deleting some object for each paint operation (be it a QPainter, and engine, or an image)
    In that case, take the one which is the easiest to implement, or, if you can measure it, the one that is the most efficient.

    EDIT:
    One other thing you can do:
    Feed the QPainter only one image, but chage the memory in the image it self.
    This will only create one Painter, with one engine.
    See QImage::loadFromData().
    ==========================signature=============== ==================
    S.O.L.I.D principles (use them!):
    https://en.wikipedia.org/wiki/SOLID_...iented_design)

    Do you write clean code? - if you are TDD'ing then maybe, if not, your not writing clean code.

  17. #16
    Join Date
    Jul 2011
    Posts
    8
    Thanks
    1

    Default Re: Memory Not Free immediatly after QPainter/QPainterDevice finish work

    got it~ thanks a lot~

Similar Threads

  1. Qdialog - free memory?
    By marc2050 in forum Newbie
    Replies: 3
    Last Post: 2nd June 2011, 03:54
  2. Free memory with QProcess
    By Luc4 in forum Qt Programming
    Replies: 3
    Last Post: 8th March 2010, 10:55
  3. Free memory
    By TomASS in forum Newbie
    Replies: 10
    Last Post: 15th February 2010, 13:50
  4. free up the memory used by QHash
    By vishal.chauhan in forum Qt Programming
    Replies: 8
    Last Post: 22nd June 2009, 19:13
  5. what is free store in C++ memory?
    By Masih in forum General Programming
    Replies: 6
    Last Post: 2nd July 2007, 22:25

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.