Python创建大字典时内存错误

2024-04-21

我正在尝试处理 3GB XML 文件,并且在读取文件并将一些数据存储在字典中的循环中间遇到内存错误。

class Node(object):
    def __init__(self, osmid, latitude, longitude):
        self.osmid = int(osmid)
        self.latitude = float(latitude)
        self.longitude = float(longitude)
        self.count = 0


context = cElementTree.iterparse(raw_osm_file, events=("start", "end"))
context = iter(context)
event, root = context.next()

for event, elem in context:
    if event == "end" and elem.tag == "node":
        lat = float(elem.get('lat'))
        lon = float(elem.get('lon'))
        osm_id = int(elem.get('id'))
        nodes[osm_id] = Node(osm_id, lat, lon)
        root.clear()

我正在使用迭代解析方法,因此问题不在于读取文件。我只想将数据存储在字典中以供以后处理,但字典似乎变得太大了。稍后在程序中,我读取链接并需要检查链接引用的节点是否在初始批次的节点中,这就是我将它们存储在字典中的原因。

我怎样才能大大减少内存占用(脚本甚至还没有接近完成,所以削减零碎的东西不会有太大帮助)或大大增加Python可用的内存量?监控内存使用情况,Python 的内存使用量约为 1950 MB,而我的计算机仍有约 6 GB 可用 RAM。


假设你有大量Node正在创建,您可以考虑使用__slots__ https://docs.python.org/3/reference/datamodel.html#slots为每个预定义一组固定的属性Node。这消除了存储每个实例的开销__dict__(以防止创建未声明的属性作为交换)并且可以轻松地减少每个内存的使用量Node约 5 倍(在 Python 3.3+ 上较少,其中共享密钥__dict__免费降低每个实例的内存成本 https://docs.python.org/3/whatsnew/3.3.html#pep-412-key-sharing-dictionary).

很简单,只需更改声明即可Node to:

class Node(object):
    __slots__ = 'osmid', 'latitude', 'longitude', 'count'

    def __init__(self, osmid, latitude, longitude):
        self.osmid = int(osmid)
        self.latitude = float(latitude)
        self.longitude = float(longitude)
        self.count = 0

例如,在 Python 3.5 上(其中共享密钥字典已经为您节省了一些东西),可以通过以下方式看到对象开销的差异:

 >>> import sys
 >>> ... define Node without __slots___
 >>> n = Node(1,2,3)
 >>> sys.getsizeof(n) + sys.getsizeof(n.__dict__)
 248
 >>> ... define Node with __slots__
 >>> n = Node(1,2,3)
 >>> sys.getsizeof(n)  # It has no __dict__ now
 72

请记住,这是具有共享密钥字典的 Python 3.5;在 Python 2 中,每个实例的成本为__slots__会类似(一个指针大小的变量更大 IIRC),而成本没有__slots__会增加几百个字节。

另外,假设您使用的是 64 位操作系统,请确保您已安装 64 位版本的 Python 以匹配 64 位操作系统;否则,Python 将被限制为约 2 GB 的虚拟地址空间,而您的 6 GB RAM 就显得微不足道了。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Python创建大字典时内存错误 的相关文章

随机推荐