Qt 5.0.2 简单 qWeb View 上的内存泄漏

Qt 5.0.2 Memory leak on simple qWebView

本文关键字:内存 泄漏 View qWeb 简单 Qt      更新时间:2023-10-16

我在Qt 5.0.2上打开QWebView时发生内存泄漏的问题。我唯一要做的就是打开一个带有简单本地网页的QWebWindow。该脚本通过执行 ajax 请求来调用服务器,并无限期地重复该操作。缓存、本地存储或会话存储中没有保存任何数据。问题是,即使在运行一个小时后,应用程序也会占用太多内存。(超过 300Mb)。

我不确定这是与qt相关的问题还是与javascript相关的问题。

这是我使用的代码:

#include <QWebFrame>
#include <QWebElementCollection>
#include <QNetworkDiskCache>
#include <QDesktopWidget>
#include <QWebHistory>
#include "mainwindow.h"
MainWin::MainWin(QWidget * parent) : QWebView(parent)
{
    m_network = new QNetworkAccessManager(this);
    m_cache = new QNetworkDiskCache(this);
    m_cache->setCacheDirectory(QStandardPaths::writableLocation(QStandardPaths::CacheLocation) + "/test");
    m_cache->setMaximumCacheSize(0);
    m_network->setCache(m_cache);
    page()->setNetworkAccessManager(m_network);
    page()->settings()->setAttribute(QWebSettings::DeveloperExtrasEnabled, true); // enable inspector
    // local content can access remote urls
    page()->settings()->setAttribute(QWebSettings::LocalContentCanAccessRemoteUrls, true);
    // enable javascript
    page()->settings()->setAttribute(QWebSettings::JavascriptEnabled, true);
    // Plug-ins must be set to be enabled to use plug-ins.
    page()->settings()->setAttribute(QWebSettings::PluginsEnabled,true);
    // Images are automatically loaded in web pages.
    page()->settings()->setAttribute(QWebSettings::AutoLoadImages,true);
    page()->settings()->setMaximumPagesInCache(0);
    page()->settings()->setObjectCacheCapacities(0,0,0); // causing slight flicker on refresh
    page()->settings()->clearMemoryCaches();
    page()->history()->setMaximumItemCount(0);
    // enable local storage
    page()->settings()->enablePersistentStorage("C:\data\");
    // hide the vertical scrollbar
    page()->mainFrame()->setScrollBarPolicy(Qt::Vertical, Qt::ScrollBarAlwaysOff);
    page()->mainFrame()->setScrollBarPolicy(Qt::Horizontal, Qt::ScrollBarAlwaysOff);

    // Signal is emitted before frame loads any web content:
    QObject::connect(page()->mainFrame(), SIGNAL(javaScriptWindowObjectCleared()),
                     this, SLOT(addJSObject()));
    setUrl(startURL);
    initEffects();
}
void MainWin::addJSObject() {
}
/*
 * EFFECTS
 */
void MainWin::initEffects() {
    resize(500, 300);
    move(0, 0); // left top corner
}
void MainWin::resize(int width, int height) {
    setGeometry(QRect(this->x(), this->y() - (height - this->height()), width, height));
}

该网页:

<html lang="en">
<head>
    <title>Details</title>
    <script type="text/javascript" src="./js/jquery-1.9.1.min.js"></script>
    <script type="text/javascript" src="./js/connection.js"></script>
</head>
<body>
    <div>page loaded: <span id="times">0</span> times</div>
</body>
</html>

和Javascript:

jQuery(document).ready(function($) {
    var counter = 0;
    var refreshData;
    refreshData = function() {
        counter++;
        var jData = '{"test":"test"}';
        var request = $.ajax({
            type: "POST",
            url: "http://qt.digia.com/",
            dataType: "json",
            data: { jsonData: jData },
            timeout: 15000,  // 15 secs
            complete: function(response) {
                console.log(response);
                delete response;
                $('#times').html(counter);
                // no need to hide the window, usual behavior
                refreshDataTimeout = setTimeout(refreshData, 1000);
            }
        });
        request.onreadystatechange = null;
        request.abort = null;
        request = null;
        delete request;
    }
    refreshData();
});

我重现了你的问题。内存增长的原因是你在javascript中使用了setTimeout( func, 1000 )。这大大增加了内存。

我使用以下代码,您的问题得到了解决。

setTimeout((function (self) { return function () {
    counter++;
    $.ajax(...);
}; })(this), 1000);

祝你好运。

函数 writeableLocation 似乎泄漏了内存。 Windows版本调用泄漏的"sHGetKnownFolderPath"。