GNU/Linux >> Linux Esercitazione >  >> Linux

Quando un processo esegue il fork, viene copiata la sua memoria virtuale o residente?

Nei sistemi moderni nessuna memoria viene effettivamente copiata solo perché viene utilizzata una chiamata di sistema fork. È tutto contrassegnato come sola lettura nella tabella delle pagine in modo tale che al primo tentativo di scrivere una trappola nel codice del kernel accadrà. Solo una volta che il primo processo tenterà di scrivere, la copia avverrà.

Questo è noto come copy-on-write.

Tuttavia potrebbe essere necessario tenere traccia anche dello spazio degli indirizzi impegnato. Se non è disponibile memoria o swap nel momento in cui il kernel deve copiare una pagina, deve terminare qualche processo per liberare memoria. Questo non è sempre desiderabile, quindi è possibile tenere traccia di quanta memoria è impegnata il kernel.

Se il kernel si impegna a più della memoria disponibile + swap, può dare un codice di errore al tentativo di chiamare fork. Se è disponibile una quantità sufficiente, il kernel eseguirà il commit per l'intera dimensione virtuale del genitore per entrambi i processi dopo il fork.


Non preoccuparti, fa una copia pigra (copia su scrittura). Gli indirizzi di memoria virtuale di entrambi i processi puntano inizialmente alle stesse pagine, ma quando il processo fork tenta di modificarlo, crea effettivamente una copia fisica della pagina (da quel momento in poi, quella pagina risiede in due punti nella RAM).

Attenzione, nessuno dei footprint di memoria segnalati in realtà ti dice quanta RAM sta utilizzando il processo. A causa dello scambio, della condivisione della memoria e di altri problemi con la memoria virtuale, è impossibile saperlo con certezza. Alcune parti dello spazio di memoria sono librerie condivise (dove contarle?), alcune si riferiscono a memoria non RAM (altri dispositivi hardware), alcune sono attualmente sostituite, altre non sono ancora state copiate (copia su scrittura) e presto. Leggi questo:

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


C'è l'impostazione del kernel

/proc/sys/vm/overcommit_memory

Citazione dall'eccellente articolo:

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.)

Questo vale sia per le forcelle che per il normale malloc. Cioè. se lo imposti su 0, fork verrà copiato su write. Copia su scrittura significa che una volta che l'app è stata biforcata, entrambe le copie condivideranno le pagine di memoria util figlio o l'originale inizia a modificare la memoria.

Nella maggior parte delle distribuzioni so che l'overcommit è 0. Ma se lo imposti su 2, tutte le pagine di memoria saranno completamente supportate dalla memoria reale e in alcuni casi sotto un'elevata pressione della memoria saranno più stabili, ma alcuni programmi (ho affrontato gitk) che si basano sugli overcommit fallirà.


Linux
  1. Linux – Quando non dovrei uccidere -9 Un processo?

  2. Codice di uscita predefinito al termine del processo?

  3. Linux – Hai bisogno di una spiegazione sulla dimensione del set residente/dimensione virtuale?

  4. Come ibernare un processo in Linux memorizzando la sua memoria su disco e ripristinandola successivamente?

  5. malloc restituisce la memoria o lo spazio degli indirizzi virtuali

Crescente utilizzo della memoria residente (RSS) di Java Process

Cosa fare quando Ctrl + C non può terminare un processo?

Quando non dovrei uccidere -9 un processo?

Picco di utilizzo della memoria di un processo

Come viene riportato l'utilizzo della memoria in Linux?

Scarica la memoria di un processo Linux su file