加载 JSON 文件时出现内存错误

2024-03-14

当我加载 500Mo 大的 JSON 文件时,Python(和间谍程序)返回 MemoryError。

但我的电脑有 32Go RAM,当我尝试加载它时,spyder 显示的“内存”从 15% 变为 19%!看来我应该有更多的空间......

有什么我没想到的吗?


500MB 的 JSON 数据不会导致 500MB 的内存使用。它将导致数倍的结果。具体是哪个因子取决于数据,但 10 - 25 的因子并不罕见。

例如,以下 14 个字符(磁盘上的字节)的简单 JSON 字符串会导致 Python 对象几乎增大 25 倍 (Python 3.6b3):

>>> import json
>>> from sys import getsizeof
>>> j = '{"foo": "bar"}'
>>> len(j)
14
>>> p = json.loads(j)
>>> getsizeof(p) + sum(getsizeof(k) + getsizeof(v) for k, v in p.items())
344
>>> 344 / 14
24.571428571428573

这是因为 Python 对象需要一些开销;实例跟踪对它们的引用数量、它们的类型以及它们的属性(如果类型支持属性)或它们的内容(如果是容器)。

如果您正在使用json内置库来加载该文件,它必须在解析内容时从内容构建越来越大的对象,并且在某一点您的操作系统将拒绝提供更多内存。不会是 32GB,因为有限制每个进程可以使用多少内存,所以更有可能是 4GB。在那时候所有那些已经创建的对象再次被释放,所以最终实际的内存使用不必改变那么多。

解决方案是将大型 JSON 文件分解为较小的子集,或者使用事件驱动的 JSON 解析器,例如ijson https://pypi.python.org/pypi/ijson.

事件驱动的 JSON 解析器不会为整个文件创建 Python 对象,只会为当前解析的项目创建 Python 对象,并通知您使用事件创建的每个项目的代码(例如“启动一个数组,这里是一个字符串,现在开始映射,这是映射的结尾,等等)。然后,您可以决定需要和保留哪些数据,以及忽略哪些数据。您忽略的任何内容都会再次被丢弃,并且内存使用量会保持在较低水平。

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

加载 JSON 文件时出现内存错误 的相关文章

随机推荐