QWebView的内存(缓存)管理

时间:2013-11-22 02:41:00

标签: pyqt qwebview qwebkit pyqt5

以下是10次下载同一页面的代码:

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

1 个答案:

答案 0 :(得分:2)

偶然发现this回答。在QT来源中引用comment

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

  2.   
  3. 当我们修剪死资源而不是释放它们时,我们将它们的记忆标记为可清除的   保持资源,直到   kernel回收了可清除的内存。

  4.         

    离开缓存中   脏居民记忆中的死资源,我们降低了可能性   内核声称内存并强迫我们重新获取内存   资源(例如,当用户按下时)。

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

按照bms20的建议,我在一个单独的进程中运行QtWebKit代码(使用subprocess.Popen)并在磁盘上缓存Web资源(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