Tak więc prowadzę krótką dyskusję z moim szefem na temat zarządzania pamięcią.
Powiedziano mi, że zabicie procesu nie pozwala na zwolnienie pamięci. Czy nadal tak jest, czy to było lata temu?
Mówimy tutaj zarówno o systemie Windows, jak i OS X.
Tak więc prowadzę krótką dyskusję z moim szefem na temat zarządzania pamięcią.
Powiedziano mi, że zabicie procesu nie pozwala na zwolnienie pamięci. Czy nadal tak jest, czy to było lata temu?
Mówimy tutaj zarówno o systemie Windows, jak i OS X.
Odpowiedzi:
Minęło dużo czasu, odkąd nauczyłem się tego, ale proszę bardzo.
Gdy system operacyjny uruchamia proces, przypisuje mu strony z tabeli pamięci wirtualnej. System operacyjny jest odpowiedzialny za utrzymanie mapy z tabeli pamięci wirtualnej do pamięci rzeczywistej lub do przestrzeni wymiany na dysku. Gdy proces zostaje zabity, system operacyjny nie tylko przestaje dawać mu cykle procesora. Robi kilka elementów czyszczących, z których jednym jest oznaczenie wszystkich stron pamięci jako wolnych. Pozwala to na ich ponowne wykorzystanie przez inne aplikacje. System operacyjny prawdopodobnie wyczyści również wszystkie uchwyty zasobów, które miał proces, automatycznie zamykając pliki, połączenia sieciowe, potoki między procesami i tak dalej. Proces ten znajduje się całkowicie pod kontrolą systemu operacyjnego i kroki te zostaną podjęte bez względu na to, jak ten proces się skończył.
Pamiętaj, że wszystko to dotyczy procesów systemu operacyjnego. Jeśli masz jakąś maszynę wirtualną, na której jest uruchomionych wiele procesów wirtualnych naraz, maszyna wirtualna jest odpowiedzialna za decyzję, jak je przydzielić i cofnąć. Jednak z systemu operacyjnego nadal wygląda jak jeden proces. Tak więc w tym jednym przypadku, jeśli masz maszynę wirtualną, która uruchamia wiele procesów i zabijesz jedną z nich w maszynie wirtualnej, prawdopodobnie nie odzyskasz natychmiast pamięci w systemie operacyjnym hosta. Ale dostaniesz go z powrotem na maszynie wirtualnej. Jeśli jednak zabijesz maszynę wirtualną w systemie operacyjnym, wówczas system operacyjny zabije maszynę wirtualną (która pośrednio zabija procesy maszyny wirtualnej) i odzyska całą pamięć (która nie będzie musiała przechodzić przez śmieciarza, free () , usuń lub cokolwiek innego).
Wysoce spekulacyjne:
Jeśli .NET działa jako maszyna wirtualna z więcej niż jedną aplikacją .NET na tej samej maszynie wirtualnej, wtedy .NET może zatrzymać pamięć, która nie jest jeszcze GCd, dopóki nie uruchomi GC, a Windows pomyśli, że .NET to używając więcej niż jest w rzeczywistości. (A jeśli MS byłby naprawdę sprytny, Windows mógłby wtedy powiedzieć .NET do GC w ciasnych pamięciach, ale prawie nie ma sensu, ponieważ do tego właśnie służy przestrzeń wymiany dysków.)
Gdyby .NET działał w ten sposób, system operacyjny nadal uważałby go za jeden proces do celów systemu operacyjnego, który bierze odpowiedzialność za podejmowanie decyzji o tym, co zachować, a co wyrzucić, a normalnym problemem systemu Windows jest powiedzenie procesowi, którego potrzebuje aby rozpocząć zwalnianie pamięci. W tym momencie można sobie wyobrazić, że MS zbuduje specjalny interfejs API tylko dla platformy .NET, tak aby procesy .NET wyglądały jak procesy systemu Windows, z wyjątkiem tego, że nimi nie są, i dlatego ludzie mogą myśleć, że pamięć procesu nie została zwolniona. To jest naprawdę; po prostu patrzysz na niewłaściwy proces.
Nie wiem wystarczająco dużo o .NET, aby powiedzieć, że tak naprawdę działa w ten sposób; Java VM na pewno nie.
Koniec spekulacji.
EDYCJA: W zakresie, w jakim zabijanie procesu jest niekorzystne dla zarządzania pamięcią, wymaga wielu procesów do przydzielenia z tej samej puli (tj. Są bardziej jak wątki niż rzeczywiste procesy) i aby pamięć nie została zwolniona po zakończeniu procesu zabity. Wymagałoby to prawie wspólnego systemu wielozadaniowości, ponieważ pamięć wirtualna i wyprzedzające wielozadaniowość były, według mojej wiedzy, zwykle wdrażane razem (maszyna wirtualna umożliwia izolowanie procesów od siebie i uniemożliwia ich wzajemne tupanie). Posiadanie pamięci wirtualnej sprawia, że czyszczenie po procesie na poziomie systemu operacyjnego jest banalne; wystarczy przenieść wszystkie strony z puli procesu do puli wolnej.
Nie ma problemu z mojego doświadczenia, zabij.
Na przykład, jeśli masz 4 GB pamięci RAM, z czego 3 GB jest używane przez grę i zabijesz proces gry, możesz ponownie uruchomić grę bez problemów i będzie ona miała ponownie 3 GB pamięci RAM na tym procesie.
Systemy operacyjne wymienione w tagach pytań (Windows i OS X) implementują pamięć wirtualną , gdzie każdy proces otrzymuje własną przestrzeń adresową, która następnie jest odwzorowywana przez system operacyjny na pamięć fizyczną. Te tabele mapowania są używane do czyszczenia przydziałów pamięci po zakończeniu procesu, więc pamięć jest całkowicie zwalniana. Strony fizyczne mogą być współużytkowane przez wiele procesów, w którym to przypadku są uwalniane, gdy nie ma już użytkowników.
Zazwyczaj inne zasoby, takie jak uchwyty plików, są przekazywane procesom w postaci możliwości , w których proces odbiera uchwyt zasobu i manipuluje nim za pomocą dobrze zdefiniowanych funkcji dostępu. System operacyjny utrzymuje mapowanie tabeli z wartości uchwytu na obiekt jądra udostępniający funkcję; ponownie, ta tabela może być użyta do czyszczenia po zakończeniu procesu.
Istnieją specjalne zasoby, które przetrwają proces, który je utworzył, na przykład możliwe jest tworzenie trwałych przydziałów nazwanej pamięci współużytkowanej, które mogą być używane w komunikacji międzyprocesowej. Są one rzadko używane, właśnie dlatego, że system operacyjny nie może ustalić, czy nadal są wymagane.
W innych systemach operacyjnych czasami nie ma wyraźnej separacji procesów; nakłada to ciężar czyszczenia na poszczególne aplikacje.
Przymusowe zamknięcie procesu spowoduje jego zakończenie bez szansy na oczyszczenie; jeśli system operacyjny ma pełną listę wszystkich zasobów, nie ma to negatywnych skutków.