3

这是下载同一页面 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 的快照:

内存从 50MB 增加到 170MB

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

奇怪的是,根据地址,消耗可能会波动,但保持在一定的阈值以下(这里是 90MB):

内存保持在 70..90MB 以内

4

1 回答 1

2

偶然发现了这个答案。引用QT 资源中的评论:

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

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

通过将缓存中的死资源留在脏常驻内存中,我们降低了内核占用该内存并强制我们重新获取资源的可能性(例如,当用户按下时)。

这种解决它..并重温我不安的灵魂。

按照 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
于 2014-01-31T03:44:57.203 回答