【问题标题】:Python running out of memory parsing XML using cElementTree.iterparse使用 cElementTree.iterparse 解析 XML 的 Python 内存不足
【发布时间】:2011-12-03 14:32:09
【问题描述】:

我的 XML 解析函数的简化版本在这里:

import xml.etree.cElementTree as ET

def analyze(xml):
    it = ET.iterparse(file(xml))
    count = 0

    for (ev, el) in it:
        count += 1

    print('count: {0}'.format(count))

这会导致 Python 内存不足,这没有多大意义。我实际存储的唯一内容是计数,一个整数。为什么会这样:

看到最后内存和 CPU 使用率突然下降了吗?那就是 Python 的崩溃。至少它给了我一个MemoryError(取决于我在循环中做了什么,它给了我更多的随机错误,比如IndexError)和一个堆栈跟踪而不是一个段错误。但是为什么会崩溃呢?

【问题讨论】:

  • stackoverflow.com/questions/1513592/… 建议在完成每个元素后调用 .clear() 以节省内存。大概这是可行的,因为 cElementTree 将先前返回的值保留在内存中。
  • @Wooble 您应该将其发布为答案。搞定了。
  • 另外,我在lxml 上取得了很好的成功;它具有相同的 (AFAIK) 功能,但内存和时间效率更高。
  • @Oliver lxml 在解析方面胜过ElementTree,但不是cElementTree
  • 请注意:这个问题似乎根本不会影响我的 Mac 上的内存,但会导致我的 Ubuntu 服务器大量消耗 RAM,就像它已经过时一样。

标签: python memory-management memory-leaks elementtree


【解决方案1】:

代码示例:

import xml.etree.cElementTree as etree

def getelements(filename_or_file, tag):
    context = iter(etree.iterparse(filename_or_file, events=('start', 'end')))
    _, root = next(context) # get root element
    for event, elem in context:
        if event == 'end' and elem.tag == tag:
            yield elem
            root.clear() # preserve memory

【讨论】:

  • 你不应该在elem 上调用clear() 吗?或者您确定只清除根目录会导致垃圾收集器也收集元素?
  • @hheimbuerger:root.clear() 就够了。我没有深入挖掘,但是当我使用它来解析大型 xml 文件时,内存使用量很小。
猜你喜欢
  • 1970-01-01
  • 2011-12-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多