Eksperymentowałem ze zmiennymi MALLOC_MMAP_THRESHOLD_ i MALLOC_MMAP_MAX_ env, aby wpłynąć na zarządzanie pamięcią w długo działającym procesie Pythona 2. Zobacz http://man7.org/linux/man-pages/man3/mallopt.3.htmlOgranicz fragmentację pamięci za pomocą MALLOC_MMAP_THRESHOLD_ i MALLOC_MMAP_MAX_
wpadłem na pomysł z tym raportu o błędzie: http://bugs.python.org/issue11849
Wyniki jakie są zachęcające: fragmentacja pamięci jest zmniejszona, a typowy znak wysokiej wody widoczne w pamięci używanej przez długotrwałych procesów jest niższa .
Moja jedyna troska dotyczy tego, czy są inne efekty uboczne, które mogą się odegrać podczas używania tak niskich poziomów. Czy ktokolwiek ma jakiekolwiek doświadczenie w ich używaniu?
Oto przykładowy skrypt, który pokazuje, w jaki sposób te zmienne wpływają na pamięć RSS w skrypcie, które generują dużą słownika: https://gist.github.com/lbolla/8e2640133032b0a6bb9c wystarczy uruchomić „alloc.sh” i porównaj wyjście. Oto wynik dla mnie:
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
Jak widać, używany RSS jest o około 20% mniej niż w przypadku Python vanilla dla tego przykładu.
Jednym ze sposobów obejścia tego problemu jest praca w rozwidlonym procesie, który następnie zostaje zakończony. – o9000
@ o9000 Nie mogę tego zrobić, ponieważ ten proces jest długotrwały. To serwer, który powinien tam być przez długi czas. – lbolla
@Ibolla można to zrobić nawet w przypadku serwerów. Rozwidlaj z procesu serwera, uruchom operację alokowania pamięci, powróć z rozwidlonego procesu do procesu serwera, zakończ proces rozwidlony, zwróć wynik do klienta, który go zażądał. To nie zawsze oznacza, że rozwiązałeś problem. Być może dane wejściowe i wyjściowe są tak duże, że i tak będą wymagać ogromnych przydziałów pamięci na serwerze. YMMV, ale możesz to zrobić. – marr75