2013-11-22 3 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_() 

А вот снимок Process Explorer, после того, как 7-й загрузки:

Memory increase from 50MB to 170MB

На 10-й загрузке память достигает 270 МБ. Это нормально? Как это исправить?

Как ни странно, в зависимости от адреса, потребление может колебаться, но при этом оставаться ниже определенного порога (здесь это 90MB):

Memory stays within 70..90MB

ответ

2

наткнулись на this ответ. Цитирование comment в источниках QT:

  1. Мертвые ресурсы в кэше хранятся в не purgeable памяти.

  2. Когда мы обрезаем мертвые ресурсы, вместо того, чтобы освободить их, мы отмечаем их память, как purgeable и сохранить ресурсы, пока ядро ​​не исправляет purgeable памяти.

оставляя в-кэш омертвевших ресурсов в грязной резидентной памяти, мы уменьшаем вероятность Ядра утверждая, что память и заставляют нас refetch на ресурса (например, когда пользователь нажимает назад).

Этот вид успокаивает его .. и переживает мою беспокойную душу.

Следуя совету BMS20, я запустить QtWebKit код в отдельном процессе (с использованием subprocess.Popen) и кэш веб-ресурсов на диске (PyQt5.QtNetwork.QNetworkDiskCache) для сохранения трафика:

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