2013-11-22 250 views
3

下面是下载相同的页面10倍的代码:QWebView的内存(缓存)管理

app = QApplication([]) 
event = threading.Event() 

def load(url): 
    def _load_finished(ok): 
    event.set() 

    web_view = QWebView() 
    web_view.loadFinished.connect(_load_finished) 
    event.clear() 
    web_view.setUrl(QUrl(url)); 
    while not event.wait(.05): app.processEvents() 
    web_view.loadFinished.disconnect(_load_finished) 
    return web_view.page().mainFrame().documentElement() 

QWebSettings.setMaximumPagesInCache(0) 
QWebSettings.setObjectCacheCapacities(0, 0, 0) 

if __name__ == '__main__': 
    for i in range(10): 
    load('http://www.huffingtonpost.com/') 
    QWebSettings.clearMemoryCaches() 
    QWebSettings.clearIconDatabase() 
    print(i) 
    app.exec_() 

这里是7下载后的Process Explorer的快照:

Memory increase from 50MB to 170MB

在第10下载内存达到270MB。 这是正常的吗?我如何解决它?

奇怪的是,根据不同的地址,消费可能出现波动,但保持低于某一阈值(这里是90MB):

Memory stays within 70..90MB

回答

2

都有所涉猎到this答案。在QT来源引用comment

  1. 缓存中的死者资源保存在非可清除内存。

  2. 当我们修剪死去的资源而不是释放它们时,我们将它们的内存标记为可清除,并保留资源直到 内核回收可清除的内存。

通过肮脏的常驻内存留在缓存 死的资源,我们减少 可能性内核声称内存和迫使我们重新抓取 资源(例如,当用户按下背面)。

这样的解决方案..并重温我不安的灵魂。

继bms20的意见,我(使用subprocess.Popen)和磁盘上(PyQt5.QtNetwork.QNetworkDiskCache)缓存Web资源保护交通运行QtWebKit代码在一个单独的进程:

部分
def ExecuteCode(code): 
    import os 
    os.environ['PYTHONIOENCODING'] = 'utf-8' #Optionally 
    from subprocess import Popen, PIPE, STDOUT 
    proc = Popen('python.exe', stdin=PIPE) 
    out, err = proc.communicate(code.encode()) 

code内容:

cache = QNetworkDiskCache() 
cache.setCacheDirectory('cache') 
web_view = QWebView() 
web_view.page().networkAccessManager().setCache(cache) 
# Do stuff with web_page 
+0

感谢您的问题和答案。是否有可能从主解释器访问web_view对象(将其添加到布局中)? – user3479125

+1

@ user3479125,“主要解释器”==主程序?如果是这样,那么我认为不是,因为'code'运行在一个单独的进程中(通过'Popen')。但是,您可以通过将其打印(内容)返回到控制台来返回子进程的页面内容。子进程退出后,内容将被存储在'out'中。此外,似乎整个QtWebKit正在被[QtWebEngine](http://doc.qt.io/qt-5/qt5-intro.html#web-engine-and-html5)所取代。我没有尝试过,但也许内存消耗没有问题。 – AlexP