加载JSON文件时出现MemoryError

时间:2016-11-03 11:06:19

标签: python json memory

Python(和spyder)在加载500Mo大的JSON文件时返回MemoryError。

但是我的电脑有一个32Go内存和#34;内存"当我尝试加载它时,由spyder显示从15%到19%!看来我还有更多的空间......

我没有想到的东西?

2 个答案:

答案 0 :(得分:8)

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

事件驱动的JSON解析器不会为整个文件创建Python对象,仅针对当前解析的项目,并通过代码通知您使用事件创建的每个项目(例如'开始一个数组,这里是一个字符串,现在开始映射,这是映射的结束等)。然后,您可以决定需要和保留哪些数据,以及忽略哪些数据。你忽略的任何东西都会被再次丢弃,内存使用率也会降低。

答案 1 :(得分:0)

所以,我将解释我是如何最终解决这个问题的。 第一个答案将起作用。但你必须知道,使用ijson加载每个元素的元素将非常长......到最后,你没有加载的文件。

因此,重要信息是窗口将每个进程的内存限制为2或4 GB ,具体取决于您使用的窗口(32或64)。如果你使用pythonxy,它将是2 GB(它只存在于32)。无论如何,这两种方式都非常低!

我通过在Windows中安装虚拟Linux解决了这个问题,但它确实有效。以下是执行此操作的主要步骤:

  1. 安装Virtual Box
  2. 安装Ubuntu (for exemple)
  3. 在计算机上为科学家安装python,like SciPy
  4. 在2台“计算机”之间创建共享文件(您将在google上找到教程)
  5. 在您的ubuntu“计算机”上执行您的代码:它可以工作;)
  6. 注意:不要忘记为虚拟计算机留出足够的RAM和内存。

    这对我有用。我不再有这个“记忆错误”问题。

    我在there发布此内容。