QWebView doesn't free its memory



  • I want to download several pages, do something with them, and free the memory they've been using. Here, the same page is downloaded 10 times:

    @#include <QApplication>
    #include <QtNetwork/QNetworkProxy>
    #include <QtWebKitWidgets/QWebView>

    void Load(char *url) {
    QWebView web_view;
    QEventLoop loop;
    QObject::connect(&web_view, SIGNAL(loadFinished(bool)), &loop, SLOT(quit()));
    web_view.setUrl(QUrl(url));
    loop.exec();
    }

    int main(int argc, char *argv[]) {
    QApplication a(argc, argv);
    QWebSettings::setMaximumPagesInCache(0);
    QWebSettings::setObjectCacheCapacities(0, 0, 0);

    for (int i = 0; i<10; ++i) {
    Load("http://www.huffingtonpost.com/");
    QWebSettings::clearMemoryCaches();
    QWebSettings::clearIconDatabase();
    printf("%d\n", i);
    }

    return a.exec();
    }@

    I would expect that QWebView is destructed at the end of each Load(), but for some reason memory usage is increasing up to 200MB and does not decrease even after we reach "return a.exec()".

    !http://s22.postimg.org/wcr5yhe81/Screenshot_2013_11_22_15_38_11.png(asd)!

    Why memory consumption is this high? How can I free it?

    P.S.: I tried adding web_view.deleteLater() at the end of Load(), but it was of no avail.



  • You called the @loop.exec()@ which doesn't return until @exit()@ is called
    (http://qt-project.org/doc/qt-4.8/qeventloop.html#exec).

    The QWebview object is never destroyed because the Load function does not return.



  • [quote author="t3685" date="1385134792"]You called the @loop.exec()@ which doesn't return until @exit()@ is called[/quote]

    True. That is why

    @ QObject::connect(&web_view, SIGNAL(loadFinished(bool)), &loop, SLOT(quit()));@

    is used (when web_view's loadFinished is emitted, loop's quit() is called. And loop's quit() is "same as exit(0)"). This means that loop.exec() returns after web_view's loadFinished is emitted and Load function returns.



  • [quote author="AlexPo" date="1385135286"][quote author="t3685" date="1385134792"]You called the @loop.exec()@ which doesn't return until @exit()@ is called[/quote]

    True. That is why

    @ QObject::connect(&web_view, SIGNAL(loadFinished(bool)), &loop, SLOT(quit()));@

    is used (when web_view's loadFinished is emitted, loop's quit() is called. And loop's quit() is "same as exit(0)"). This means that loop.exec() returns after web_view's loadFinished is emitted and Load function returns.
    [/quote]

    I am assuming you are working single-threaded? If so, the loadFinished signal (in actuality a fuction) will never be called because you never return to the main event loop.



  • [quote author="t3685" date="1385151492"]
    I am assuming you are working single-threaded?[/quote]

    Yes. In fact, code written here is all there is. :)

    [quote author="t3685" date="1385151492"]
    If so, the loadFinished signal (in actuality a fuction) will never be called because you never return to the main event loop.[/quote]

    Can you be more specific? Do you mean I should return to the main event loop by calling "a.exec()" or "QApplication::exec()", and not "loop.exec()"? Is return to and enter the main event loop the same thing? If so, "loop.exec()":http://qt-project.org/doc/qt-5.0/qtcore/qeventloop.html#exec, according to the documentation, enters the main event loop, hence catching loadFinished signal.



  • Try to print out the i in your loop, to make sure I am not mistaken :). If you always see i = 0 then I'm probably right.

    Then you should probably read this to get some more insight in the Qt event system:

    http://qt-project.org/wiki/ThreadsEventsQObjects

    I am assuming you are trying to load a web page and delete the object once the web page is loaded. What I don't understand is why you make an additional QEventLoop as well.



  • [quote author="t3685" date="1385210105"]Try to print out the i in your loop, to make sure I am not mistaken :). If you always see i = 0 then I'm probably right.[/quote]

    What loop are you referring to? If to the for loop at lines 18..23, then i is already being printed out at line 22, and I confirm that all 10 i's (from 0 to 9) are printed. You can easily check it by creating Qt Console App and copying code into main.cpp.

    [quote author="t3685" date="1385210105"]
    Then you should probably read this to get some more insight in the Qt event system:

    http://qt-project.org/wiki/ThreadsEventsQObjects
    [/quote]

    I did and what I saw was the same "approach":http://qt-project.org/wiki/ThreadsEventsQObjects#7494f2b4836907fc1c09311e3a0305e6 I am using.

    [quote author="t3685" date="1385210105"]
    I am assuming you are trying to load a web page and delete the object once the web page is loaded.
    [/quote]

    Yep. And doing something after page is loaded, but I omitted this step for simplicity.

    [quote author="t3685" date="1385210105"]
    I am assuming you are trying to load a web page and delete the object once the web page is loaded. What I don't understand is why you make an additional QEventLoop as well.
    [/quote]

    Additional to QApplication::exec()? If "yes", then the problem with QApplication's loop is that once quit() (or exit()) is called, QApplication stops working (pages cannot be loaded), and I don't want that (correct me if I am wrong). There are other ways but the one code uses is the simplest, AFAIK.



  • You are right every iteration is printed out. I misjudged the problem then :). Can you give a short summary of what you are trying to do? Because normal Qt code does require making a QEventLoop.



  • I need to:

    1. Load a page and wait until it is completely loaded (specifically, I am interested in javascript to complete execution).
    2. Process content of that page (e.g. save html to HDD). Note: after this step I don't need page in RAM anymore.
    3. Goto step 1 after some time.

    Everything works as expected, except program's usage of RAM increases dramatically as iteration repeats. I want to stop the increase of mem usage and to level it off by forgetting old pages (freeing cached/loaded resources) .

    As seen in the code, I am trying to achieve this by calling QWebSettings' functions (those that I could find) that restrict mem usage, also, QWebView is destructed at the end of Load() in a hope that resources related to loading of a page also would be destructed (and therefore freed), but, as graph shows, without any success.


Log in to reply
 

Looks like your connection to Qt Forum was lost, please wait while we try to reconnect.