Ho sperimentato le variabili di env MALLOC_MMAP_THRESHOLD_ e MALLOC_MMAP_MAX_ per influenzare la gestione della memoria in un processo Python 2 a esecuzione prolungata. Vedere http://man7.org/linux/man-pages/man3/mallopt.3.htmlRidurre la frammentazione della memoria con MALLOC_MMAP_THRESHOLD_ e MALLOC_MMAP_MAX_
ho avuto l'idea da questo bug report: http://bugs.python.org/issue11849
I risultati che ho sono incoraggianti: la frammentazione della memoria è ridotta e il marchio tipico di alta acqua visibile in memoria utilizzata da processi di lunga durata è inferiore .
La mia unica preoccupazione è se ci sono altri effetti collaterali che possono mordere indietro, quando si utilizzano ritocchi di livello così basso. Qualcuno ha qualche esperienza nel usarli?
Ecco uno script di esempio che mostra come queste variabili influenzano la memoria RSS in uno script che generano un dizionario di grandi dimensioni: https://gist.github.com/lbolla/8e2640133032b0a6bb9c basta eseguire "alloc.sh" e confrontare l'output. Ecco l'output per me:
MALLOC_MMAP_THRESHOLD_=None MALLOC_MMAP_MAX_=None
N=9 RSS=120968
MALLOC_MMAP_THRESHOLD_=512 MALLOC_MMAP_MAX_=None
N=9 RSS=157008
MALLOC_MMAP_THRESHOLD_=1024 MALLOC_MMAP_MAX_=None
N=9 RSS=98484
MALLOC_MMAP_THRESHOLD_=2048 MALLOC_MMAP_MAX_=None
N=9 RSS=98484
MALLOC_MMAP_THRESHOLD_=4096 MALLOC_MMAP_MAX_=None
N=9 RSS=98496
MALLOC_MMAP_THRESHOLD_=100000 MALLOC_MMAP_MAX_=None
N=9 RSS=98528
MALLOC_MMAP_THRESHOLD_=512 MALLOC_MMAP_MAX_=0
N=9 RSS=121008
MALLOC_MMAP_THRESHOLD_=1024 MALLOC_MMAP_MAX_=0
N=9 RSS=121008
MALLOC_MMAP_THRESHOLD_=2048 MALLOC_MMAP_MAX_=0
N=9 RSS=121012
MALLOC_MMAP_THRESHOLD_=4096 MALLOC_MMAP_MAX_=0
N=9 RSS=121000
MALLOC_MMAP_THRESHOLD_=100000 MALLOC_MMAP_MAX_=0
N=9 RSS=121008
MALLOC_MMAP_THRESHOLD_=512 MALLOC_MMAP_MAX_=16777216
N=9 RSS=157004
MALLOC_MMAP_THRESHOLD_=1024 MALLOC_MMAP_MAX_=16777216
N=9 RSS=98484
MALLOC_MMAP_THRESHOLD_=2048 MALLOC_MMAP_MAX_=16777216
N=9 RSS=98484
MALLOC_MMAP_THRESHOLD_=4096 MALLOC_MMAP_MAX_=16777216
N=9 RSS=98496
MALLOC_MMAP_THRESHOLD_=100000 MALLOC_MMAP_MAX_=16777216
N=9 RSS=98528
Come si può vedere, RSS utilizzata è di circa il 20% in meno rispetto alla vaniglia Python per questo esempio.
Un modo per aggirare questo problema è eseguire il processo in un processo biforcuto che quindi viene chiuso. – o9000
@ o9000 Non posso farlo perché il processo in questione è di lunga durata. È un server, dovrebbe essere lì da molto tempo. – lbolla
@Ibolla puoi farlo anche in casi di server. Forcella dal processo del server, eseguire l'operazione di allocazione della memoria, il ritorno dal processo biforcato al processo del server, terminare il processo biforcuto, restituire il risultato al client che lo ha richiesto. Ora, questo non significa sempre che hai risolto il problema. Forse l'input e l'output sono così grandi da richiedere comunque enormi allocazioni di memoria sul server. YMMV ma puoi farlo. – marr75