2016-07-23 16 views
10

Wygląda na to, że python3.5 nie całkowicie zwalnia pamięć dowolnego usuniętego obiektu, może to być spowodowane tym, że pyton wewnętrznie utrzymuje pewien rodzaj puli memorialów w celu ponownego użycia, jednak nie chcę ich ponownie używać i chcę je zwolnić aby udostępnić pamięć dla innych programów działających na Linuksie.Jak zwolnić pamięć usuniętego obiektu Pythona?

>>> psutil.Process().memory_info().rss/2**20 
11.47265625 
>>> d = {x:x for x in range(10**7)} 
>>> psutil.Process().memory_info().rss/2**20 
897.1796875 
>>> del d 
>>> gc.collect() 
0 
>>> psutil.Process().memory_info().rss/2**20 
15.5859375 

To tylko zabawny przykład, prawdziwym problemem jest uruchomiony serwer, zabierający 20GB niewymuszonej pamięci.

Oto kolejny przykład: (WD1 jest DICT z dict z kluczami tekstowymi)

>>> psutil.Process().memory_info().rss/2**20 
28.1796875 
>>> wd1 = {x:{i:i for i in d} for x in k} 
>>> psutil.Process().memory_info().rss/2**20 
682.78125 
>>> del wd1 
>>> psutil.Process().memory_info().rss/2**20 
186.21484375 
+0

Nie masz kontroli nad zarządzaniem pamięcią w pythonie (lub innym nowoczesnym języku z automatycznym lub półautomatycznym zarządzaniem pamięcią). – Daniel

+0

To jest naprawdę problem, kiedy musimy używać Pythona w programie serwera, jak zmodyfikować kod źródłowy python3.5, aby był on dostępny na serwerach? –

+0

Po prostu myśl, ale co z wykorzystaniem podprocesu lub modułów wieloprocesowych do wykonania dużych porcji pracy? Gdy proces linuksowy zostanie zakończony, czy nie odzyskasz całej swojej pamięci? * jak zmodyfikować źródło python3.5 ... * wydaje mi się, że to nie starter, przynajmniej dla mnie. –

Odpowiedz

6

Po usunięciu obiektu jest ona dostępna na śmieci zebranych zamiast natychmiast usunięty - tak po prostu dać mu trochę czasu i zwolni lub uruchomi się gc.collect(), aby przyspieszyć działanie.

python.exe 
Python 3.5.1 (v3.5.1:37a07cee5969, Dec 6 2015, 01:38:48) [MSC v.1900 32 bit (Intel)] on win32 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import psutil 
>>> import gc 
>>> psutil.Process().memory_info().rss/2**20 
13.2890625 
>>> d = {x:x for x in range(10**7)} 
>>> psutil.Process().memory_info().rss/2**20 
359.13671875 
>>> del d 
>>> psutil.Process().memory_info().rss/2**20 
13.5234375 
>>> gc.collect() 
0 
>>> psutil.Process().memory_info().rss/2**20 
13.4375 
>>> 

Tylko dla odniesienia powłoki Python 3 jest w rzeczywistości bardziej jak ipython 2 w którym znajduje się pewna ilość pamięci wzięte z historii, itd., Tylko dla odniesienia:

Python 3.5.1 (v3.5.1:37a07cee5969, Dec 6 2015, 01:38:48) [MSC v.1900 32 bit (Intel)] on win32 
Type "help", "copyright", "credits" or "license" for more information. 
>>> import psutil 
>>> psutil.Process().memory_info().rss/2**20 
13.1875 
>>> psutil.Process().memory_info().rss/2**20 
13.20703125 
>>> psutil.Process().memory_info().rss/2**20 
13.20703125 
>>> psutil.Process().memory_info().rss/2**20 
13.20703125 
>>> psutil.Process().memory_info().rss/2**20 
13.20703125 
>>> 22*3 
66 
>>> psutil.Process().memory_info().rss/2**20 
13.25390625 
>>> import gc 
>>> psutil.Process().memory_info().rss/2**20 
13.25390625 
>>> gc.collect() 
0 
>>> psutil.Process().memory_info().rss/2**20 
13.171875 
>>> 

Następnego dnia rano aby sprawdzić, czy robi aktualizacji dict w funkcji jest inna:

>>> psutil.Process().memory_info().rss/2**20 
13.1484375 
>>> D = {} 
>>> psutil.Process().memory_info().rss/2**20 
13.1484375 
>>> def UpdateD(d, v): 
...  """ Add the text and value for v to dict d """ 
...  d[v] = str(v) 
... 
>>> psutil.Process().memory_info().rss/2**20 
13.16015625 
>>> for x in range(10**7): 
...  UpdateD(D, x) 
... 
>>> psutil.Process().memory_info().rss/2**20 
666.6328125 
>>> del D 
>>> psutil.Process().memory_info().rss/2**20 
10.765625 
>>> gc.collect() 
0 
>>> psutil.Process().memory_info().rss/2**20 
12.8984375 
>>> 

Tak wygląda kod produkcyjny może być wiszące na odniesienie że trzeba jeszcze wytropić.

+1

Tak samo jak dla osób nie znających gc, będzie to czasowo blokować, więc na pewno nie jest czymś, co można wywołać w środku wrażliwej na czas logiki. – David

+0

Czekałem 30 minut, i uruchomiłem gc.collect() kilka razy, nadal pokazuje 15.5859375, nie uwolniono –

+0

to samo dzieje się w procesie serwera, nie tylko na powłoce python3, niewymawialny i nie gc kolekcjonerski –

Powiązane problemy