我正在尝试在Linux Mint上使用lxml的HTMLPullParser,但我发现内存使用量不断增加,我不知道为什么。这是我的测试代码:
# -*- coding: utf-8 -*-
from __future__ import division, absolute_import, print_function, unicode_literals
import lxml.etree
import resource
from io import DEFAULT_BUFFER_SIZE
for _ in xrange(1000):
with open('StackOverflow.html', 'r') as f:
parser = lxml.etree.HTMLPullParser()
while True:
buf = f.read(DEFAULT_BUFFER_SIZE)
if not buf: break
parser.feed(buf)
parser.close()
# Print memory usage
print((resource.getrusage(resource.RUSAGE_SELF)[2] * resource.getpagesize())/1000000.0)
StackOverflow.html是stackoverflow的主页,我将其保存在与python脚本相同的文件夹中。我已经尝试添加显式删除和清除,但到目前为止没有任何工作。我做错了什么?
答案 0 :(得分:1)
解析器构造的元素正在泄漏,我无法在代码中看到导致它的API合同违规。由于对象在使用gc.collect()
运行的手动垃圾回收中幸存,因此最好的办法是尝试使用不同的解析策略作为解决方法。
要查看根本原因,我使用了内存探索模块objgraph并安装了xdot来查看它创建的图表。
在运行代码之前,我跑了:
In [3]: import objgraph
In [4]: objgraph.show_growth()
运行代码后,我跑了:
In [6]: objgraph.show_growth()
tuple 1616 +147
_Element 146 +146
list 1100 +24
wrapper_descriptor 1423 +15
weakref 1155 +6
getset_descriptor 677 +4
dict 2777 +4
member_descriptor 315 +3
method_descriptor 891 +2
_TempStore 2 +1
In [7]: import random
In [8]: objgraph.show_chain(
...: objgraph.find_backref_chain(
...: random.choice(objgraph.by_type('_Element')), objgraph.is_proper_module))
Graph written to /tmp/objgraph-bfuwa9.dot (8 nodes)
Spawning graph viewer (xdot)
注意:根据所查看的网页,这些数字可能与您看到的数字不同。