Cuando un proceso se bifurca, ¿se copia su memoria virtual o residente?


12

La forma estándar de hacer nuevos procesos en Linux es que la huella de memoria del proceso padre se copia y se convierte en el entorno del proceso hijo hasta que execvse llama.

¿De qué huella de memoria estamos hablando, el virtual (lo que solicitó el proceso) o el residente (lo que realmente se está utilizando)?

Motivación: tengo un dispositivo con espacio de intercambio limitado y una aplicación con una gran diferencia entre la huella de memoria virtual y residente. La aplicación no se puede bifurcar debido a la falta de memoria y le gustaría ver si ayudar a reducir el tamaño de la huella virtual.

Respuestas:


12

En los sistemas modernos, ninguna de la memoria se copia en realidad solo porque se utiliza una llamada de sistema fork. Todo está marcado como de solo lectura en la tabla de páginas, de modo que en el primer intento de escribir una trampa en el código del kernel sucederá. Solo una vez que el primer proceso intente escribir, se realizará la copia.

Esto se conoce como copia en escritura.

Sin embargo, también puede ser necesario realizar un seguimiento del espacio de direcciones comprometido. Si no hay memoria o intercambio disponible en el momento en que el núcleo tiene que copiar una página, tiene que matar algún proceso para liberar memoria. Esto no siempre es deseable, por lo que es posible realizar un seguimiento de cuánta memoria se ha comprometido con el núcleo.

Si el núcleo se compromete a más de la memoria + intercambio disponible, puede dar un código de error al intentar llamar a fork. Si hay suficiente disponible, el núcleo se comprometerá con el tamaño virtual completo del padre para ambos procesos después de la bifurcación.


1
If enough is available the kernel will commit to the full virtual size of the parent for both processes after the fork.Si, gracias. Esto significa que la reducción de la huella virtual del proceso en un entorno con memoria limitada (RAM e intercambio) podría resolver el problema de no poder bifurcar.
TheMeaningfulEngineer

1
@ Alan Sí. Si forkfalla con un mensaje de error que indica que la memoria es insuficiente. Luego, reducir el uso de memoria virtual del proceso antes de bifurcar podría ayudar.
kasperd

5

No te preocupes, hace una copia perezosa (copia en escritura). Las direcciones de memoria virtual de ambos procesos apuntan a las mismas páginas inicialmente, pero cuando el proceso bifurcado intenta modificarlo, en realidad hace una copia física de la página (a partir de ese momento, esa página reside en dos lugares en su RAM).

Tenga cuidado, ninguna de las huellas de memoria informadas en realidad le dice qué cantidad de RAM está usando el proceso. Debido al intercambio, el intercambio de memoria y otros problemas con la memoria virtual, es imposible saberlo con certeza. Algunas partes del espacio de la memoria son bibliotecas compartidas (¿dónde contarlas?), Algunas se refieren a la memoria que no es RAM (otros dispositivos de hardware), algunas están actualmente intercambiadas, algunas todavía no se han copiado (copiar en escritura) y pronto. Lee esto:

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


5

Hay configuración del núcleo

/ proc / sys / vm / overcommit_memory

Cita de excelente artículo :

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

Esto se aplica tanto a las horquillas como a los malloc regulares. Es decir, si lo establece en 0, la bifurcación se copiará al escribir. Copiar al escribir significa que una vez que la aplicación se bifurca, ambas copias compartirán las páginas de memoria del niño o del original y comenzarán a cambiar la memoria.

En la mayoría de las distribuciones, sé que el exceso de compromiso es 0. Pero si lo configura en 2, todas las páginas de memoria estarán completamente respaldadas por memoria real y, en algunos casos, bajo presión de memoria alta, serán más estables, pero algunos programas (me enfrenté a gitk) que dependen en sobrecompromisos fallará.

Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.