Zawieś / wznów pojedynczy proces na / z dysku

22

Czasami chcielibyśmy zawiesić procesy wymagające dużej ilości pamięci na naszych serwerach Ubuntu i OS X, aby tymczasowo zwolnić trochę pamięci RAM na inne zadania. Gdybyśmy tylko martwili się wykorzystaniem procesora, prosty Ctrl-Zdziałałby. Musimy jednak być w stanie zwolnić pamięć RAM (zapisując ją na dysk), a następnie ponownie uruchomić proces (dysk -> RAM) lub innymi słowy „hibernować” pojedynczy proces. Wszelkie wskazówki, jak to zrobić? (Najlepiej z CLI.) Dzięki.

Mike Covington
źródło
7
Podejrzewam, że kiedy proces jest w stanie zawieszenia, jego używana pamięć jest kandydatem do zamiany na dysk, jeśli to konieczne, i powinno to być zrobione automatycznie z jądra.
enzotib
1
@enzotib - Nie mam pojęcia, czy tak się dzieje i teoretycznie brzmi dobrze. Jednak właśnie wykonałem trudny test i w praktyce to nie działa. Wszelkie nowe procesy odradzające się, gdy „zjadacze pamięci RAM” są zawieszone, są bardzo powolne i nie wykrywam żadnej aktywności dysku, która byłaby oczekiwana, gdyby RAM zamieniano na dysk.
Mike Covington
1
@frozenwithjoy Mogę potwierdzić, że tak się dzieje. Jedyne powody, dla których mogę myśleć o tym, że zawieszony proces nie byłby stopniowo zamieniany, to jeśli zażąda pamięci, której nie można wymienić (dość rzadka i (głównie) zarezerwowana dla użytkownika root), lub jeśli pamięć, którą mapuje, jest współdzielona z innym, aktywnym procesem .
Gilles „SO- przestań być zły”
1
Terminem, który może tu pomóc, jest „punkt kontrolny” (tak, brzydka forma czasownika). Jest to na ogół trudny problem, ponieważ program może korzystać z niektórych zasobów, które mogą zmienić stan, gdy program śpi. Zarządzanie tym problemem było kiedyś jedną z różnic między Big Iron a małymi, zbzikowanymi komputerami.
dmckee

Odpowiedzi:

8

Nie ma ogólnej możliwości hibernacji pojedynczego procesu, tylko cały system.

Jeśli jednak nie przejmuje się tym, że obraz procesu nie przetrwa ponownego uruchomienia, istnieje wbudowane narzędzie do zapisywania obrazu procesu na dysku: zamiana. Upewnij się, że masz wystarczająco dużo przestrzeni wymiany, a jeśli występuje presja pamięci, a proces nie jest aktywny (na przykład ponieważ jest zawieszony), jego pamięć zostanie wymieniona.

Jeśli wiesz, że proces będzie prawdopodobnie nieaktywny przez długi czas i że w pewnym momencie będziesz potrzebować szybkiego czasu reakcji, możesz wymusić zwolnienie dużej ilości pamięci RAM poprzez przydzielenie dużej ilości pamięci RAM w proces krótkotrwały, np

perl -e '$tmp = "a" x 999999999' # allocate about 1GB

Nie masz żadnej kontroli nad tym, co zostanie zamienione, więc inne procesy mogą zostać zamienione. W systemie Linux możesz z powrotem zamienić proces, wymuszając dostęp do mapowanych stron. Skrypt w tej odpowiedzi zrobi to: załaduje do pamięci wszystkie strony odwzorowane przez proces (zwróć uwagę, że obejmuje to otwarte pliki; możesz przechodzić przez regiony selektywnie na podstawie informacji mapy, aby uniknąć zamiany danych, o których wiesz, że nie będziesz potrzebować zobacz tę odpowiedź, aby uzyskać więcej informacji).

Gilles „SO- przestań być zły”
źródło
13

Termin, którego szukasz, to „ Punkt kontrolny aplikacji ”.

Znane mi narzędzia, które mogą to zrobić, to CryoPID i CryoPID2 .

Oba narzędzia są przeznaczone tylko dla systemu Linux.

Nie znam podobnego narzędzia dla BSD lub OS X.

Ikem
źródło
2
Inną aplikacją jest DMTCP: dmtcp.sourceforge.net
Deer Hunter
5

Upewnij się, że masz dużo przestrzeni wymiany. Upewnij się, że twój system woli zmieniać nieaktywne strony ( vm.swappiness = 100 ). Wtedy powinno wystarczyć zawieszenie procesu. Jądro woli wymieniać nieaktywne strony.

David Schwartz
źródło
-1

W systemie Mac OS X możesz spróbować użyć purgepolecenia (dostarczonego z Xcode), aby zwolnić część (nieaktywnej) pamięci RAM.

vm_stat
purge
vm_stat
Jefz
źródło
2
purgenie pomogłoby tutaj. Usuwa pamięć podręczną dysku, ale nie spowoduje to zamiany pamięci procesu i nie przyspieszy innego procesu uzyskania pamięci RAM.
Gilles „SO- przestań być zły”