Słyszałem wiele razy, że gdy program zarządzany w C# zażądał więcej pamięci od systemu operacyjnego, nie zwalnia go, chyba że systemowi brakuje pamięci. Na przykład. gdy obiekt jest zbierany, zostaje usunięty, a pamięć zajmowana przez obiekt może zostać ponownie wykorzystana przez inny obiekt zarządzany, ale sama pamięć nie jest zwracana do systemu operacyjnego (na przykład mono na systemie UNIX nie wywołuje nazwy brk
/sbrk
zmniejszyć ilość pamięci wirtualnej dostępnej dla procesu z powrotem do tego, co było przed jej przydzieleniem).czy mono/.Net GC zwalnia wolną przydzieloną pamięć z powrotem do systemu operacyjnego po pobraniu? jeśli nie, dlaczego?
Nie wiem, czy to naprawdę się dzieje, czy nie, ale widzę, że moje aplikacje C#, działające na Linuksie, używają małej ilości pamięci na początku, a kiedy robię coś drogiego, to przydzielają więcej , ale później, gdy wszystkie obiekty zostaną usunięte (mogę to zweryfikować, umieszczając komunikat debugowania w destruktorze), pamięć nie jest wolna. Z drugiej strony, po ponownym uruchomieniu tej kosztownej operacji pamięci nie jest już przydzielana żadna pamięć. Program po prostu kontynuuje spożywanie tej samej ilości pamięci, aż do jej zakończenia.
Może to tylko moje niezrozumienie, jak GC w .net działa, ale jeśli to naprawdę działa, dlaczego tak jest? Co to jest korzyść z utrzymywania przydzielonej pamięci na później, zamiast zwracania jej z powrotem do systemu? Jak może nawet wiedzieć, czy system potrzebuje go z powrotem, czy nie? A co z inną aplikacją, która uległa awarii lub nie mogła się uruchomić z powodu OOM spowodowanej przez ten efekt?
Wiem, że ludzie prawdopodobnie odpowiedzą na coś w rodzaju: "GC zarządza pamięcią lepiej niż kiedykolwiek, po prostu nie przejmuj się tym" lub "GC wie, co robi najlepiej" lub "to w ogóle nie ma znaczenia, to tylko wirtualna pamięć ", ale to ma znaczenie, na moim laptopie 2GB korzystam z OOM (i z tego powodu uruchamiany jest OOM z kernela) bardzo często, gdy po jakimś czasie uruchamiam aplikacje C# właśnie z powodu nieodpowiedzialnego zarządzania pamięcią.
Uwaga: Testowałem to wszystko na mono w Linuksie, ponieważ naprawdę ciężko mi zrozumieć, jak okna zarządzają pamięcią, więc debugowanie na Linuksie jest dla mnie o wiele łatwiejsze, także zarządzanie pamięcią linuksową to open source code, zarządzanie pamięcią okien kernel/.Net jest dla mnie dość tajemniczy.
Nie jestem odpowiedzią, ale polecam wyszukać artykuły/filmy z [Maoni Stephens] (http://channel9.msdn.com/posts/Maoni-Stephens-CLR-45-Server-Background-GC). Jest deweloperem GC Lead ... – rene
To jest bardzo specyficzny problem z Linuksem, masz to, o co prosiłeś. Po prostu [wyłącz to] (http://jurjenbokma.com/ApprenticesNotes/turing_off_overcommit.html). –