2010-04-02 7 views
11

Mam program, który implementuje kilka heurystycznych algorytmów wyszukiwania i kilka domen, zaprojektowanych do eksperymentalnej oceny różnych algorytmów. Program napisany jest w C++, zbudowany przy użyciu toolchaina GNU i uruchomiony w 64-bitowym systemie Ubuntu. Po uruchomieniu eksperymentów używam polecenia bash, aby ograniczyć ilość pamięci wirtualnej, której może użyć proces, aby mój system testowy nie zaczął się zamieniać.Dlaczego mój program czasami odskakuje, gdy brakuje pamięci, zamiast rzucać std :: bad_alloc?

Niektóre kombinacje algorytmów/instancji testowych trafiają w zdefiniowany przeze mnie limit pamięci. W większości przypadków program generuje wyjątek std :: bad_alloc, który jest drukowany przez domyślny program obsługi, w którym to momencie program się kończy. Czasami, zamiast tego, program po prostu się psuje.

Dlaczego mój program okazjonalnie wyskakuje, gdy brakuje pamięci, zamiast zgłaszać nieobsługiwane std :: bad_alloc i kończy działanie?

+0

Błąd segfault może być spowodowany nie tylko dlatego, że osiągnął limit pamięci – Andrey

+0

Jestem w pełni świadomy. W przypadkach, w których widziałem segfault, proces wykorzystywał ilość pamięci w pobliżu określonego przeze mnie limitu. Jestem przekonany, że wykryte błędy nie wynikały z błędów w moim kodzie. –

+1

Czy rozważałeś prosty przebieg w GDB (Cóż, kilka z nich), aby zobaczyć, która część kodu seg-faults? – Shiroko

Odpowiedz

8

Jednym z powodów może być to, że domyślnie Linux nadmiernie pochłania pamięć. Żądanie pamięci z jądra wydaje się działać poprawnie, ale później, gdy faktycznie zaczniesz korzystać z pamięci, jądro zauważy "O cholera, zabraknie mi pamięci", wywołuje zabójcę spoza pamięci (OOM), który wybiera niektóre proces ofiary i zabija go.

Do opisu tego zachowania, zobacz http://lwn.net/Articles/104185/

+0

Prawdopodobnie. Jeszcze więcej informacji, pracowałem jako jedyny użytkownik w systemie testowym, który ma 48 GB pamięci. Byłem uruchomiony z ulimitem o wielkości 47GB pamięci wirtualnej, który powinien pozostawiać wiele pamięci rdzeniowej dla systemu operacyjnego. Linkowany artykuł pochodzi z 2004 roku. Czy jest on nadal aktualny? –

1

Co janneb powiedział. W rzeczywistości Linux domyślnie nigdy wyrzuca std :: bad_alloc (lub zwraca NULL z malloc()).

+0

Zakładam, że masz na myśli "std :: bad_alloc nigdy nie jest domyślnie wyrzucany na Linuksie". Dlaczego więc widzę std :: bad_alloc wyrzucony z programów C++ na kilka systemów Linux, gdy program osiągnie limit pamięci? –

+0

Ponadto, myślę, że masz na myśli 'malloc 'zamiast' wolna'. Strona podręcznika Linux dla malloc nie sprawia, że ​​brzmi jak NULL, nigdy nie zostanie zwrócona. –

+0

@Bradford. Oczywiście masz rację. Naprawiony. –

1

Może to być kod za pomocą polecenia no-throw new i nie sprawdzającego wartości zwracanej.

Albo jakiś kod może uchwycić wyjątek i nie obsługiwać go lub ponownie go podrzucać.

Powiązane problemy