2013-11-22 110 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