Why is the memory of a qwebpage's test increasing all the time?

860 views Asked by At

Consider:

    QString urls[] = {
        QString("http://www.sina.com")
    };
    int len = 1;
    QWebSettings::setMaximumPagesInCache(0);
    QEventLoop loop;
    for (int i = 0; i < 200000; i++) {
        QWebPage *page = new QWebPage;
        page->settings()->setAttribute(
                    QWebSettings::AutoLoadImages,
                    false);
        page->settings()->setAttribute(
                    QWebSettings::PrintElementBackgrounds,
                    false);
        page->settings()->setAttribute(
                    QWebSettings::JavascriptEnabled,
                    false);
        QString url = urls[i % len];
        cout << "requesting " << url.toStdString() << endl;
        connect(page, SIGNAL(loadFinished(bool)),
                &loop, SLOT(quit()));
        page->mainFrame()->load(url);
        loop.exec();
        disconnect(page, 0, 0, 0);
        QWebSettings::clearMemoryCaches();
        page->settings()->clearMemoryCaches();
        connect(page, SIGNAL(destroyed()),
                &loop, SLOT(quit()));
        printLog(page->mainFrame()->toHtml());
        page->deleteLater();
        loop.exec();
    }

When this test is executed, the memory increase from about 40 MB to about 700 MB. It looks like a memory leak exists in my code. But it seems that all the objects are deleted. Why is this?

2

There are 2 answers

2
László Papp On BEST ANSWER

This was a known issue already in 2009. Unfortunately, the person who had brought up the issue did not go further to actually file a bugreport. You can read the corresponding thread here:

http://marc.info/?l=webkit-dev&m=124888472218111&w=2

I would suggest to go ahead and create a bug report if it is still present with Qt 5.2.

Note that, in an ideal world, as written, you should not have a heap object for this operation, although it is slightly off-topic as it would not fix your issue. Yet, it is better to be aware of that a stack object here would do your job without the manual deletion headache.

4
vahancho On

I would try to rewrite your code in the following way:

QString urls[] = {
    QString("http://www.sina.com");
};
int len = 1;
QWebSettings::setMaximumPagesInCache(0);
QEventLoop loop;
QWebPage page;
for (int i = 0; i < 200000; i++) {
    page.settings()->setAttribute(QWebSettings::AutoLoadImages, false);
    page.settings()->setAttribute(QWebSettings::PrintElementBackgrounds, false);
    page.settings()->setAttribute(QWebSettings::JavascriptEnabled, false);
    QString url = urls[i % len];
    cout << "requesting " << url.toStdString() << endl;
    connect(page, SIGNAL(loadFinished(bool)), &loop, SLOT(quit()));
    page.mainFrame()->load(url);
    loop.exec();

    QWebSettings::clearMemoryCaches();
    page.settings()->clearMemoryCaches();
    printLog(page.mainFrame()->toHtml());
}

It is much simpler and does not require explicit memory allocation.