2015-06-19 15 views
5

Contextbash kod błędu 137 vs 1, gdy z pamięci

uruchomić następujące polecenie w linux bash:

mono --debug --debugger-agent=transport=dt_socket,address=198.178.155.198:10000 ./Stress.exe 

Stress.exe jest aplikacją C#.

Co dzieje

W pewnym momencie system jest z pamięci, co jest potrzebne. Zwracany jest kod błędu.

Kod błędu zwrócony (echo $?)

Kod 1: Gdy mój program tworzy rzut bo to z pamięci.

Kod 137: Gdy zostanie zabity przez system operacyjny w przypadku przeciążenia pamięci.

Pytanie

Dlaczego jest to jakiś system operacyjny, który zabija mój wniosek? Dlaczego wynik nie zawsze jest taki sam?

+0

Używasz Linuksa? –

+0

Tak !! Chociaż Bash był zawsze linuxem? – Cher

+0

^^ Nie, [ tag: cygwin] ... – anishsane

Odpowiedz

3

Zakładając:

  • Mono działa GC oparciu o SGEN
  • Linux OOM killer jest faktycznie włączone
  • Twój Stress.exe jest tylko alloc'ing udało pamięć tj No Native współdziałanie, brak użycia dzielników pamięci Marshaling, żaden kod nie jest oznaczony jako niebezpieczny, itp.
  • Ciągle tworzysz obiekty i nigdy nie zwalniasz ich fs.

porozmawiajmy SGEN, tak jak wy, Alloc obiektów, są one tworzone w przedszkolu, jak zabraknie pamięci w przedszkolu, kiedy GC robi zamiatać i musi zrobić kolekcję przedszkola, ponieważ jest pełna , żywe obiekty są przenoszone na dużą stertę. Jeśli główna głowica jest pełna, wymagana jest większa pamięć systemu operacyjnego. Możesz dostosować ilość pamięci początkowej przydzielonej do aplikacji mono, a nawet ustalić ilość pamięci (maks.), Którą może wykorzystać Sgen. Zarządzane obiekty o wielkości ponad 8000 bajtów są obsługiwane przez duży obiekt Space Manager Sgen, a to jest pamięć typu innego niż przedszkole/duże sterty, ale nadal jest to obiekt/pamięć zarządzana.

Zwykle, gdy mono potrzebuje więcej miejsca dla zarządzanych obiektów i wykonuje żądanie systemu operacyjnego dla dodatkowego bloku, a system operacyjny mówi NIE, widzisz wyjątek OutOfMemory i twój kod wyjścia 0. Twój test stresu jest szczęśliwy.

Ale OOM obserwuje ten proces mono i dostosowuje jego wynik (oom_score) coraz wyżej. Mogłoby to w każdej chwili zaatakować ten monofoniczny proces, ale dałbym do zrozumienia, że ​​jest to właściwe w momencie zamiany GC, gdy wątki aplikacji są zawieszone przez SGEN, ale zanim SGEN faktycznie wykona żądanie pamięci systemu operacyjnego z powodu braku zarządzania przestrzeń pamięci w nusery. W ten sposób otrzymasz wyjście 137.137 & 127 = 9, więc proces mono został wysłany sygnałem SIGKILL (kill -9), a test stresu nie jest zadowolony.

Spróbuj to jako eksperyment:

  • 1) Jeśli wyłączysz zabójcy OOM całkowicie. Zakładając, że to nie jest pudełko na żywo produkcji , powinieneś zauważyć ;-) Powinieneś zobaczyć "System.OutOfMemoryException" w 100% przypadków.
  • lub 2) Ustaw oom_adj tylko jednego procesu mono na -17, a OOM pozostawi go w spokoju. Po prostu zawijamy mono uruchomić w skrypcie powłoki, aby pobrać jego pid i echo -17 do oom_adj tego procesu.
  • lub 3) Jeśli ustawisz oom_adj procesu mono na niższy (aż do -16, wtedy zobaczysz mono przechwytujący swoją własną awarię pamięci zarządzanej "więcej czasu", ale nigdy nie będzie to 100% czas ...

To nie jest problem związany z Mono i/lub Sgen/GC Każdy proces zużywający coraz więcej pamięci podlega OOM zabity. baza danych lub po prostu aplikacja/demon, który ma wyciek pamięci, itp. Wszystkie one podlegają zabiciu.

+0

dzięki! naprawdę jasne, dlaczego tak się stało, a twoje prognozy były rzeczywiście poprawne! – Cher

+0

Awesome !, Cieszę się, że mogę pomóc. – SushiHangover

Powiązane problemy