JSON大文件解析内存爆炸主因是json.load()强制全量构建对象树;应区分NDJSON格式逐行解析,或用ijson流式提取指定路径字段,单对象深度嵌套场景需推动上游格式优化。

因为 json.load() 和 json.loads() 必须把整个 JSON 文本一次性构建成完整的 Python 对象树,而 Python 对象本身有大量元数据、引用计数和哈希表开销——3GB 的文件,内存常飙到 10GB+。
json.load() 会把整个文件塞进内存,不是“读得慢”,是“根本没打算分块”
它不区分你只需要 "user.name" 还是全部字段,也不管嵌套有多深。只要顶层是个 {} 或 [],它就递归展开每一层,为每个字符串分配新内存、为每个 dict 建哈希表、为每个 list 预留扩容空间。
- 错误典型:
json.load(open('logs.json'))加载一个单对象、含百万条日志的{"events": [...]},进程 RSS 瞬间突破容器内存限制 - 验证方式:用
tracemalloc.start()+get_top_stats(5),你会看到 top 3 全是dict.__init__、list.append、str.__new__ - 注意:
json.load()不支持 partial read,哪怕你只传入io.BytesIO(f.read(1024)),它也会报JSONDecodeError: Extra data
你以为是“大 JSON”,其实可能是 NDJSON(JSONL)格式
很多所谓“大 JSON 文件”其实是每行一个独立 JSON 对象,比如日志导出、API 批量响应。这种格式不能用 json.load(),必须手动按行切分再调用 json.loads()。
- ✅ 正确识别:
head -n 3 huge.json看是否每行都以{或[开头,且能单独被json.loads()解析 - ❌ 错误操作:
json.load(f)直接喂给多行文本,必然失败,报错常是Expecting value或Unterminated string(实际是内存不足导致解析中途崩溃) - 安全做法:逐行读 +
strip()+ 跳过空行 +try/except json.JSONDecodeError,别依赖json.decoder.whitespace
ijson 是目前最稳妥的流式替代方案,但路径写错就等于白用
ijson 底层用 C 扩展,按需触发事件,不建完整对象,适合提取深层字段(如 data.items.author.name)。但它不是万能的——路径匹配失败时静默跳过,不会报错,容易漏数据。
立即学习“Python免费学习笔记(深入)”;
- 安装:
pip install ijson(注意:Windows 上可能需先装visualcppbuildtools) - 关键参数:
ijson.parse(f)返回事件流;ijson.items(f, 'records.item')提取指定路径下所有对象 - 陷阱:
'records.item'中的records必须是顶层 key,若实际是{"response": {"records": [...]}},就得写'response.records.item' - 性能提示:用
bytes模式打开文件(open(..., 'rb')),避免 UTF-8 解码开销;别在循环里反复调用ijson.items()
真正难处理的是单对象、深度嵌套、又不能改格式的 JSON——这时候连 ijson 都可能因路径太深或字符串太长触发 RecursionError 或 MemoryError。别硬扛,优先推动上游拆分或转存为 Parquet / SQLite。


















