QWebView 的内存(缓存)管理
Posted
技术标签:
【中文标题】QWebView 的内存(缓存)管理【英文标题】:QWebView's memory (cache) management 【发布时间】:2013-11-22 02:40:59 【问题描述】:这是下载同一页面 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 的快照:
第 10 次下载内存达到 270MB。 这是正常的吗?我该如何解决?
奇怪的是,根据地址,消耗可能会波动,但会保持在一定的阈值以下(这里是 90MB):
【问题讨论】:
【参考方案1】:偶然发现this 的答案。在 QT 资源中引用 comment:
缓存中的死资源保存在不可清除的内存中。
当我们修剪死资源而不是释放它们时,我们将它们的内存标记为可清除并 保留资源直到 内核回收可清除内存。
通过离开缓存 脏常驻内存中的死资源,我们降低了 内核声称该内存并迫使我们重新获取 资源(例如,当用户按下回时)。
这种方式解决了它..并重温我不安的灵魂。
按照 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
【讨论】:
感谢您的提问和回答。是否可以从主解释器访问 web_view 对象(将其添加到布局中)? @user3479125,“主解释器”==主程序?如果是这样,那么我认为不会,因为code
在单独的进程中运行(通过Popen
)。但是,您可以通过将其(内容)打印到控制台来返回子进程页面的内容。子进程退出后,内容将存储在out
。此外,似乎整个 QtWebKit 正在被 QtWebEngine 取代。没试过,不过内存消耗可能没有问题。以上是关于QWebView 的内存(缓存)管理的主要内容,如果未能解决你的问题,请参考以下文章
Linux 内核 内存管理内存管理架构 ③ ( Linux 内核中的内存管理模块 | 页分配器 | 不连续页分配器 | 内存控制组 | 硬件设备内存管理 | MMU | 页表缓存 | 高速缓存 )
Linux 内核 内存管理内存管理架构 ③ ( Linux 内核中的内存管理模块 | 页分配器 | 不连续页分配器 | 内存控制组 | 硬件设备内存管理 | MMU | 页表缓存 | 高速缓存 )