python / python/cpython

C Unpickler memory leak when unpickling big geojsons

オープン
#121,569 コメント 3 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

type-bug
主要言語
Python
スター
77.2k
フォーク
35.9k
PR マージ指標
PR 指標を取得中

説明

Bug report

Bug description:

I noticed that the pickle.load method leaves more memory allocated than just the size of the returned object when unpickling geojson dictionaries.

I initially noticed the leak in my docker container running on x86. Here is a code snippet that reproduced the problem for me on M1 MacOS Sonoma (python 3.11.9).

import io
import pickle

import psutil

process = psutil.Process()

to_pickle = {
    "type": "FeatureCollection",
    "crs": {"properties": {"name": "EPSG:4326"}, "type": "name"},
    "features": [
        {
            "type": "Feature",
            "id": f"id{idx}",
            "properties": {
                "str_prop": f"str_var{idx}",
                "int_prop": idx,
                "bool_prop": bool(idx % 2),
                "none_prop": None,
                "float_prop": float(idx),
            },
        }
        for idx in range(9000)
    ],
}
b = pickle.dumps(to_pickle)
del to_pickle

print(
    f"Initial memory usage: {round(int(process.memory_info().rss / 1024) / 1024, 3)}MiB"
)
pickle.Unpickler(io.BytesIO(b)).load()
print(
    f"After 1st unpickle memory usage: {round(int(process.memory_info().rss / 1024) / 1024, 3)}MiB"
)
for i in range(1000):
    pickle.Unpickler(io.BytesIO(b)).load()

print(
    f"Final memory usage: {round(int(process.memory_info().rss / 1024) / 1024, 3)}MiB"
)
CPython versions tested on:

3.11

Operating systems tested on:

Linux, macOS

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

まず、提供された Python 再現プログラムを影響を受ける CPython バージョンで実行し、pickle.Unpickler(...).load() の呼び出しを繰り返した後のメモリを比較します。これらのネストされた辞書に使用される C Unpickler の経路を追跡します。繰り返し unpickling を行っても報告された過剰なメモリが割り当てられたままにならず、このケースの回帰テストが追加されれば完了です。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
c, python
領域
backend, performance
issue の種類
バグ
難易度
4/5
見積もり時間
3〜5日
活発さ
停滞
明瞭さ
おおむね明確
初心者へのやさしさ
35/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。