Mam skrypt w języku Python, który importuje duży plik CSV, a następnie zlicza liczbę wystąpień każdego słowa w pliku, a następnie eksportuje liczby do innego pliku CSV.
Ale to, co się dzieje, to to, że po zakończeniu liczenia części i rozpoczęciu eksportu, Killed
na terminalu jest napisane .
Nie sądzę, że jest to problem z pamięcią (zakładam, że wystąpiłby błąd pamięci, a nie Killed
).
Czy to możliwe, że ten proces trwa zbyt długo? Jeśli tak, czy istnieje sposób na przedłużenie limitu czasu, abym mógł tego uniknąć?
Oto kod:
csv.field_size_limit(sys.maxsize)
counter={}
with open("/home/alex/Documents/version2/cooccur_list.csv",'rb') as file_name:
reader=csv.reader(file_name)
for row in reader:
if len(row)>1:
pair=row[0]+' '+row[1]
if pair in counter:
counter[pair]+=1
else:
counter[pair]=1
print 'finished counting'
writer = csv.writer(open('/home/alex/Documents/version2/dict.csv', 'wb'))
for key, value in counter.items():
writer.writerow([key, value])
A Killed
dzieje się po finished counting
wydrukowaniu, a pełna wiadomość to:
killed (program exited with code: 137)
killed
pochodzi wiadomość, ale jeśli wynika to z przekroczenia pewnego rodzaju limitu pamięci systemowej, możesz to naprawić, używająccounter.iteritems()
zamiastcounter.items()
w ostatniej pętli. W Pythonie 2items
zwraca listę kluczy i wartości w słowniku, który może wymagać dużo pamięci, jeśli jest bardzo duży. W przeciwieństwie do tegoiteritems
jest to generator, który wymaga tylko niewielkiej ilości pamięci w danym momencie.Odpowiedzi:
Kod zakończenia 137 (128 + 9) wskazuje, że program zakończył pracę z powodu odebrania sygnału 9, czyli
SIGKILL
. To również wyjaśniakilled
przesłanie. Pytanie brzmi, dlaczego otrzymałeś ten sygnał?Najbardziej prawdopodobną przyczyną jest prawdopodobnie przekroczenie przez proces pewnego ograniczenia ilości zasobów systemowych, których możesz używać. W zależności od systemu operacyjnego i konfiguracji może to oznaczać, że masz zbyt wiele otwartych plików, zużyłeś zbyt dużo miejsca w pamięci plików lub coś innego. Najprawdopodobniej Twój program zużywał zbyt dużo pamięci. Zamiast ryzykować, że coś się zepsuje, gdy alokacje pamięci zaczną się nie powieść, system wysłał sygnał zabicia do procesu, który zużywał zbyt dużo pamięci.
Jak wspomniałem wcześniej, jednym z powodów, dla których możesz przekroczyć limit pamięci po wydrukowaniu,
finished counting
jest to, że twoje wywołaniecounter.items()
w ostatniej pętli przydziela listę zawierającą wszystkie klucze i wartości z twojego słownika. Jeśli Twój słownik zawiera dużo danych, może to być bardzo duża lista. Możliwym rozwiązaniem byłoby użyciecounter.iteritems()
generatora. Zamiast zwracać wszystkie elementy z listy, umożliwia ich iterację przy znacznie mniejszym zużyciu pamięci.Proponuję więc wypróbować to jako ostatnią pętlę:
for key, value in counter.iteritems(): writer.writerow([key, value])
Zauważ, że w Pythonie 3
items
zwraca obiekt „widoku słownika”, który nie ma takiego samego narzutu, jak wersja Pythona 2. Zastępujeiteritems
, więc jeśli później zaktualizujesz wersje Pythona, w końcu zmienisz pętlę z powrotem do stanu, w jakim była.źródło
W grę wchodzą dwa obszary przechowywania: stos i sterta. Stos jest miejscem, w którym przechowywany jest bieżący stan wywołania metody (tj. Zmienne lokalne i odwołania), a sterta to miejsce, w którym przechowywane są obiekty. rekurencja i pamięć
Wydaje mi się, że w dyktycie jest zbyt wiele kluczy,
counter
które będą zużywać zbyt dużo pamięci regionu sterty, więc środowisko wykonawcze Pythona zgłosi wyjątek OutOfMemory .Aby go zapisać, nie twórz gigantycznego obiektu, np. Licznika .
1.StackOverflow
program, który tworzy zbyt wiele zmiennych lokalnych.
Python 2.7.9 (default, Mar 1 2015, 12:57:24) [GCC 4.9.2] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> f = open('stack_overflow.py','w') >>> f.write('def foo():\n') >>> for x in xrange(10000000): ... f.write('\tx%d = %d\n' % (x, x)) ... >>> f.write('foo()') >>> f.close() >>> execfile('stack_overflow.py') Killed
2.OutOfMemory
program, który tworzy giganta,
dict
zawiera zbyt wiele kluczy.>>> f = open('out_of_memory.py','w') >>> f.write('def foo():\n') >>> f.write('\tcounter = {}\n') >>> for x in xrange(10000000): ... f.write('counter[%d] = %d\n' % (x, x)) ... >>> f.write('foo()\n') >>> f.close() >>> execfile('out_of_memory.py') Killed
Bibliografia
źródło
Wątpię, żeby cokolwiek zabijało ten proces tylko dlatego, że zajmuje dużo czasu. Zabicie generalnie oznacza, że coś z zewnątrz zakończyło proces, ale prawdopodobnie nie w tym przypadku naciśnięcie Ctrl-C, ponieważ spowodowałoby to zamknięcie Pythona w przypadku wyjątku KeyboardInterrupt. Ponadto w Pythonie można uzyskać wyjątek MemoryError, jeśli to był problem. To, co może się dziać, to błąd w Pythonie lub standardowym kodzie biblioteki, który powoduje awarię procesu.
źródło
SIGKILL
, chyba że Python maraise(SIGKILL)
gdzieś w swoim kodzie z jakiegoś powodu.Najprawdopodobniej zabrakło pamięci, więc Kernel zabił twój proces.
Czy słyszałeś o OOM Killer ?
Oto dziennik ze skryptu, który opracowałem do przetwarzania ogromnego zestawu danych z plików CSV:
Mar 12 18:20:38 server.com kernel: [63802.396693] Out of memory: Kill process 12216 (python3) score 915 or sacrifice child Mar 12 18:20:38 server.com kernel: [63802.402542] Killed process 12216 (python3) total-vm:9695784kB, anon-rss:7623168kB, file-rss:4kB, shmem-rss:0kB Mar 12 18:20:38 server.com kernel: [63803.002121] oom_reaper: reaped process 12216 (python3), now anon-rss:0kB, file-rss:0kB, shmem-rss:0kB
Został wzięty z
/var/log/syslog
.Gruntownie:
Oto artykuł o zachowaniu OOM .
źródło
Po prostu miałem to samo, gdy próbowałem uruchomić skrypt Pythona z folderu współdzielonego w
VirtualBox
nowym Ubuntu 20.04 LTS. Python wyłączył sięKilled
podczas ładowania mojej własnej biblioteki. Kiedy przeniosłem folder do katalogu lokalnego, problem zniknął. Wygląda na to, żeKilled
zatrzymanie nastąpiło podczas początkowego importu mojej biblioteki, ponieważ po przeniesieniu folderu otrzymałem komunikaty o brakujących bibliotekach.Problem zniknął po ponownym uruchomieniu komputera.
Dlatego ludzie mogą chcieć spróbować przenieść program do katalogu lokalnego, jeśli jest to jakiś udział lub może to być przejściowy problem, który wymaga tylko ponownego uruchomienia systemu operacyjnego.
źródło