Kiedy proces rozwidla się, kopiowana jest jego pamięć wirtualna lub rezydentna?

12

Standardowym sposobem tworzenia nowych procesów w systemie Linux jest kopiowanie śladu pamięci procesu nadrzędnego, który staje się środowiskiem procesu potomnego, dopóki nie execvzostanie wywołany.

O jakim śladzie pamięci mówimy, wirtualnym (o co prosił proces) czy rezydentnym (co jest faktycznie używane)?

Motywacja: Mam urządzenie z ograniczoną przestrzenią wymiany i aplikację z dużą różnicą między powierzchnią pamięci wirtualnej a rezydentną. Aplikacja nie może rozwidlać się z powodu braku pamięci i chciałaby sprawdzić, czy próba zmniejszenia wirtualnego rozmiaru śladu pomogłaby.

TheMeaningfulEngineer
źródło

Odpowiedzi:

12

W nowoczesnych systemach żadna pamięć nie jest kopiowana tylko dlatego, że używane jest wywołanie systemowe typu fork. Wszystko jest oznaczone jako „tylko do odczytu” w tabeli stron, tak że przy pierwszej próbie zapisania pułapki w kodzie jądra. Kopiowanie nastąpi tylko po pierwszej próbie zapisu.

Jest to znane jako kopiowanie przy zapisie.

Konieczne może być jednak również śledzenie przydzielonej przestrzeni adresowej. Jeśli w momencie, gdy jądro musi skopiować stronę, nie ma dostępnej pamięci ani wymiany, musi zabić proces, aby zwolnić pamięć. Nie zawsze jest to pożądane, więc można śledzić, ile pamięci zajęło jądro.

Jeśli jądro zgodzi się na więcej niż dostępna pamięć + zamiana, może podać kod błędu przy próbie wywołania fork. Jeśli dostępna jest wystarczająca ilość jądra, zatwierdza pełny wirtualny rozmiar rodzica dla obu procesów po rozwidleniu.

kasperd
źródło
1
If enough is available the kernel will commit to the full virtual size of the parent for both processes after the fork.Tak dziękuję. Oznacza to, że zmniejszenie wirtualnego śladu procesowego w środowisku o ograniczonej pamięci (RAM i swap) może rozwiązać problem niemożności rozwidlenia.
TheMeaningfulEngineer
1
@Alan Tak. Jeśli się forknie powiedzie z komunikatem o błędzie wskazującym niewystarczającą pamięć. Pomoże to zmniejszyć zużycie pamięci wirtualnej przez proces przed rozwidleniem.
kasperd
5

Nie martw się, tworzy leniwą kopię (kopiowanie przy zapisie). Adresy pamięci wirtualnej obu procesów początkowo wskazują na te same strony, ale gdy rozwidlony proces próbuje go zmodyfikować, faktycznie tworzy fizyczną kopię strony (od tej pory strona ta znajduje się w dwóch miejscach w pamięci RAM).

Uwaga, żaden ze zgłoszonych śladów pamięci nie mówi, ile pamięci RAM zużywa proces. Ze względu na zamianę, współdzielenie pamięci i inne problemy z pamięcią wirtualną nie można tego wiedzieć na pewno. Niektóre części pamięci są bibliotekami współdzielonymi (gdzie je policzyć?), Niektóre odnoszą się do pamięci innej niż RAM (inne urządzenia sprzętowe), niektóre są obecnie zamienione, niektóre nie są jeszcze kopiowane (kopiowanie przy zapisie) i wkrótce. Przeczytaj to:

https://lwn.net/Articles/642202/

orion
źródło
5

Jest ustawienie jądra

/ proc / sys / vm / overcommit_memory

Cytat z doskonałego artykułu :

Since 2.5.30 the values are: 0 (default): as before: guess about how much  
overcommitment is reasonable, 1: never refuse any malloc(), 2: be precise 
about the overcommit - never commit a virtual address space larger than swap 
space plus a fraction overcommit_ratio of the physical memory. Here 
/proc/sys/vm/overcommit_ratio (by default 50) is another user-settable 
parameter. It is possible to set overcommit_ratio to values larger than 100. 
(See also Documentation/vm/overcommit-accounting.)

Dotyczy to zarówno widelców, jak i zwykłego malloc. To znaczy, jeśli ustawisz na 0, widelec będzie kopiowany podczas zapisu. Kopiowanie przy zapisie oznacza, że ​​po rozwidleniu aplikacji obie kopie będą współużytkować strony pamięci, ponieważ dziecko lub oryginał zaczyna zmieniać pamięć.

W większości dystrybucji wiem, że nadmiar jest równy 0. Ale jeśli ustawisz go na 2, wszystkie strony pamięci będą w pełni wspierane przez rzeczywistą pamięć, aw niektórych przypadkach pod wysokim ciśnieniem pamięci będą bardziej stabilne, ale niektóre programy (w obliczu gitk) polegają na overcommitach zawiedzie.

gena2x
źródło