2013-04-28 16 views
34

AKTUALIZACJA: - Ten problem został rozwiązany po ponownym uruchomieniu komputera. Nie można jeszcze ustalić przyczyny tego błędu.Zwolnienie pamięci ogromnej tablicy numpy w IPython

Mam funkcję, która ładuje ogromną tablicę numpy (~ 980MB) i zwraca ją.

Kiedy po raz pierwszy uruchamiam Ipython i wywołuję tę funkcję, ładuje ona tablicę do zmiennej bez żadnego problemu.

Ale jeśli ponownie uruchomię to samo polecenie, wyjście spowoduje zgłoszenie "Błąd pamięci".

Próbowałem następujących,

del hugeArray 

Wciąż ten sam błąd został występujących. Próbowałem nawet następującą

del hugeArray 
gc.collect() 
gc.collect() 

Początkowo gc.collect() zwrócone 145 i drugie połączenie wrócił 48. Ale nawet po tym, kiedy należy wywołać funkcję, to wciąż podnosząc błąd pamięci.

Jedynym sposobem, który mógłbym załadować ponownie, był restart ipython. Czy jest coś, co mogę zrobić, aby zwolnić całą pamięć w ipythonie, więc nie muszę jej restartować?

---------------- Aktualizacja

Poniżej znajduje się wyjście %whos

Variable Type  Data/Info 
------------------------------ 
gc   module <module 'gc' (built-in)> 
gr   module <module 'Generate4mRamp' <...>rom 'Generate4mRamp.pyc'> 
np   module <module 'numpy' from '/us<...>ages/numpy/__init__.pyc'> 
plt  module <module 'matplotlib.pyplo<...>s/matplotlib/pyplot.pyc'> 

się z tego, gr mój moduł zawierający funkcję, która użyłem do załadowania kostki danych.

--------- Jak odtworzyć błąd

Poniższa prosta funkcja jest w stanie odtworzyć błędu.

import numpy as np 
import gc 

def functionH(): 
    cube=np.zeros((200,1024,1024)) 
    return cube 

testcube=functionH() #Runs without any issue 

del testcube 
testcube=functionH() # Raises Memory Error 

del testcube 
gc.collect() 
gc.collect() 
testcube=functionH() # Still Raises Memory Error 

Ten błąd występuje tylko w ipython. W prostym pythonie (>>>) po nadaniu del testcube, nie ma błędu pamięci.

+1

Czy możesz spróbować wywołać 'whos' w ipythonie, aby dowiedzieć się, co zajmuje pamięć? – tiago

+0

@tiago: Dodałem dane wyjściowe polecenia% whos. Nie pokazuje niczego oprócz modułów, które wczytałem. – indiajoe

+0

Czy możesz wyświetlić liczbę referencyjną obiektu przed usunięciem? 'import sys; sys.getrefcount (testcube)' – HYRY

Odpowiedz

43

Czy patrzysz na wartość? IPython buforuje zmienne wyjściowe, np. Out[8], więc jeśli go zbadasz, będzie on przechowywany w pamięci.

Możesz zrobić %xdel testcube, aby usunąć zmienną i usunąć ją z pamięci podręcznej IPythona. Alternatywnie, %reset out lub %reset array usunie całą twoją historię wydruków lub tylko odniesienia do numpy tablic.

+0

Nie patrzyłem na wartość w IPython. Ale dziękuję za te informacje o buforowaniu wyjść przez Ipython. Nie wiedziałem o tym. Wypróbuję tę komendę xdel również, gdy ten błąd wystąpi następnym razem. Teraz wszystko działa dobrze. – indiajoe

+2

Czy istnieje powód, dla którego to nie działa poprawnie? Próbuję zrobić coś takiego jak 'list ([i ** 2 for i in range (30000000)])', aby przetestować to, a następnie spróbuję wykonać% reset. Out jest pusty, ale pamięć jest nadal zajęta, jak przed poleceniem resetu, dlaczego to możliwe? To tak, jakby usunąć tylko referencję. ale nie zwalniając pamięci? – Marko

+0

Powinienem dodać, że% reset, bez 'out' wykonuje pracę. Opróżnia pamięć i usuwa odniesienia. Ale nie chcę tracić własnych zmiennych. Działa to również 'v = Out [18]% xdel v'. Dlaczego? – Marko