Quando un fork di processo viene copiato la sua memoria virtuale o residente?


12

Il modo standard di creare nuovi processi in Linux è che l'impronta di memoria del processo genitore viene copiata e che diventa l'ambiente del processo figlio fino a quando non execvviene chiamato.

Di quale footprint di memoria stiamo parlando, quello virtuale (ciò che il processo ha richiesto) o quello residente (cosa viene effettivamente utilizzato)?

Motivazione: ho un dispositivo con spazio di scambio limitato e un'applicazione con una grande differenza tra footprint di memoria virtuale e residente. L'applicazione non può essere spostata a causa della mancanza di memoria e vorrebbe vedere se provare a ridurre le dimensioni dell'impronta virtuale sarebbe di aiuto.

Risposte:


12

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

Questo è noto come copia su scrittura.

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

Se il kernel si impegnasse in più della memoria disponibile + scambio, può dare un codice di errore nel tentativo di chiamare fork. Se è disponibile una quantità sufficiente, il kernel si impegnerà per l'intera dimensione virtuale del genitore per entrambi i processi dopo il fork.


1
If enough is available the kernel will commit to the full virtual size of the parent for both processes after the fork.Si Grazie. Ciò significa che ridurre l'impronta virtuale del processo in un ambiente con memoria limitata (RAM e swap) potrebbe risolvere il problema di non essere in grado di fork.
TheMeaningfulEngineer,

1
@Alan Sì. Se forkfallisce con un messaggio di errore che indica memoria insufficiente. Quindi può essere utile ridurre l'utilizzo della memoria virtuale del processo prima del fork.
Kasperd,

5

Non ti preoccupare, 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 biforcato tenta di modificarlo, in realtà crea una copia fisica della pagina (da quel momento in poi, quella pagina risiede in due punti nella RAM).

Attenzione, nessuna delle impronte di memoria segnalate in realtà indica la quantità di RAM utilizzata dal 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 alla memoria non RAM (altri dispositivi hardware), alcune sono attualmente scambiate, altre non ancora copiate (copia su scrittura) e presto. Leggi questo:

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


5

C'è un'impostazione del kernel

/ Proc / sys / vm / overcommit_memory

Citazione da 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 per forcelle e malloc regolari. Vale a dire se lo si imposta su 0, fork verrà copiato in scrittura. Copia su scrittura significa che una volta che l'app è stata biforcuta, entrambe le copie condivideranno le pagine di memoria utilizzando il figlio o l'originale inizia a cambiare memoria.

Nella maggior parte delle distribuzioni so che il sovraccarico è 0. Ma se lo si imposta su 2, tutte le pagine di memoria saranno completamente supportate dalla memoria reale e in alcuni casi ad alta pressione di memoria saranno più stabili, ma alcuni programmi (ho affrontato gitk) che fanno affidamento in caso di sovraccarico fallirà.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.