当前位置: 首页 > 知识库问答 >
问题:

Python Py魅力:加载大型JSON文件时内存不足

周飞
2023-03-14

为了加载几个大的(~200MB) JSON文件,执行了以下代码:

def work():
    jsons = get_data()
    # do something with the jsons

def get_data():
    json_files = []
    for json_path in file_paths_list:
        json_files.append(load_json(json_path))
    return json_files

def load_json(json_path):
    import json
    with open(json_path) as f:
        return json.load(f)

以下是 Pycharm 的自定义 VM 选项的外观(最大 30GB 堆大小,RAM 为 32GB):

# custom PyCharm VM options

-Xms25000m
-Xmx30000m
...
...
...

已应用“使缓存失效/重新启动”的流行建议。

加载2个文件(总计约400MB)后,在第三次加载期间,引发异常“MemoryError”。

我不明白为什么如果我有高达30GB的堆大小,内存错误抛出后只有400MB?

共有1个答案

叶俊郎
2023-03-14

PyCharm是Python IDE,而不是Python解释器。它使用的内存用于编辑阶段。

由于 python 对象的开销,400MB 的文件很可能会扩展到几 GB 的数据(可能不是 30 个,而是 3 或 4 个)。例:

>>> s = "hello"
>>> import sys
>>> sys.getsizeof(s)
54

基本上 RAM 中对象的大小远高于字符串的大小。

所以如果你的python解释器是32位的解释器,你有2GB或者3GB的限制,可以解释这个。PyCharm使用64位内核,但是无法帮助解释器部分。

升级到64位解释器,它可以利用你所有的内存。

您可以查看版本信息

>>> import sys
>>> sys.version

例如,我得到:

('3.4.3 (v3.4.3:9b73f1c3e601, Feb 24 2015, 22:44:40) [MSC v.1600 64 bit '
 '(AMD64)]')

如果它显示“32位”,我的猜测是正确的。因此,请卸载32位版本

您可能需要在新安装中安装其他模块,因此最好在卸载之前转储需求文本文件,以便能够在新的64位版本上执行全局pip安装

 类似资料:
  • 问题内容: 我有一个1.2 GB的json文件,当反序列化时,应该给我一个包含15百万个对象的列表。 我要反序列化的计算机是具有16核心和32 GB Ram的Windows 2012服务器(64位)。 该应用程序已针对x64构建。 尽管有这种情况,当我尝试读取json文档并将其转换为我遇到内存不足异常的对象列表时。当我查看任务管理器时,我发现仅使用了5GB内存。 我尝试的代码如下。 一个。 b。

  • 问题内容: 我想将包含字符串的巨大文件合并为一个文件,并尝试使用nio2。我不想将整个文件加载到内存中,因此我尝试了BufferedReader: 我对此进行了尝试,但是,它的工作原理,字符串的格式(例如,新行等未复制到合并文件中): 如何在不将整个文件加载到内存的情况下将大型文件与NIO2合并? 问题答案: 如果您想有效地合并两个或多个文件,则应问自己,为什么要使用基础文件并执行该任务。 通过使

  • 我想插入多个实时模板。例如,每当我键入<code>prop</code>并按<code>tab</code>时,pycharm就会为python编写完整的属性。 我想导入以下列表:https://github.com/hoffmann/PyCharm-Python-Templates 但是我在< code >中找不到templates文件夹 我也在使用社区版2016.1.4。

  • 您可以将现有的实时模板文件添加到pycharm 2020.1,只需: < li >转到此位置:~/。config/JetBrains/pycharmce 2020.1 < li >创建名为:templates的新文件夹 < li >将您的文件放入此文件夹中 < li >重新启动pycharm 谢了。 此链接到 odoo 模板:https://gitlab.com/mramadan2711/odoo

  • 基于@ari答案的解决方案我已经更新了代码。现在它被优化到只使用1MB(我不知道这是否是将进程分成块的最佳方式,但现在它似乎得到了改进,并且不提供OOM)。我将尝试通过检测可以使用多少堆内存来进一步优化它,但我不确定是否可以实现这一点。直到比这似乎是最好的选择。再次感谢@Ari。