python / python/cpython

C Unpickler memory leak when unpickling big geojsons

Aperta
#121,569 3 commenti 0 reazioni 0 assegnatari Vedi su GitHub

Nessuno ha ancora preso questa issue.

type-bug
Lingua principale
Python
Stelle
77.2k
Fork
35.9k
Metriche di merge delle PR
Metriche PR in attesa

Descrizione

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

Guida per i contributori

Apri la guida per i contributori

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Direzione di ricerca

Inizia eseguendo il riproduttore Python fornito sulle versioni di CPython interessate e confronta la memoria dopo chiamate ripetute a pickle.Unpickler(...).load(). Traccia il percorso C Unpickler usato per questi dizionari annidati; il lavoro è completato quando l’unpickling ripetuto non lascia più allocata la memoria in eccesso segnalata e viene aggiunto un test di regressione per il caso.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Valutazione

Stack tecnologico
c, python
Ambito
backend, performance
Tipo di issue
Bug
Difficoltà
4/5
Tempo stimato
3-5 giorni
Stato di attività
Ferma
Chiarezza
Abbastanza chiara
Idoneità per principianti
35/100

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.