El modelo teórico para un programador de nivel de aplicación hace que parezca que esto es así. En realidad, el proceso de inicio normal (al menos en 1.x Linux, creo 2.xy 3.x están optimizados pero similar) es:
- El kernel crea un contexto de proceso (más o -menos, máquina virtual)
- en ese contexto proceso, se define un mapeo de memoria virtual que se asigna de direcciones de memoria RAM para el inicio de su archivo ejecutable
- Suponiendo que usted está vinculada de forma dinámica (por defecto/habitual), el programa
ld.so
(por ejemplo, /lib/ld-linux.so.2
) definido en los encabezados de su programa configura la asignación de memoria para las bibliotecas compartidas
- El kernel hace un
jmp
en la rutina de inicio de su programa (para un programa C, algo así como crtprec80
, que llama al main
). Como solo ha configurado la asignación y no ha cargado ninguna página (*), esto causa una falla de página de la Unidad de administración de memoria de la CPU, que es una interrupción (excepción, señal) para el kernel.
- El controlador de fallas de página del kernel carga alguna sección de su programa, incluida la parte que causó el error de página, en la memoria RAM.
- Como su programa se ejecuta, si accede a una dirección virtual que no tiene RAM de respaldo en este momento, se producirán fallas de página y hará que el núcleo suspenda brevemente el programa , cargue la página del disco y luego devolver el control al programa.Todo esto ocurre "entre instrucciones" y normalmente no se puede detectar.
- Al usar
malloc
/new
, el kernel crea páginas de lectura y escritura de RAM (sin archivos de respaldo de disco) y las agrega a su espacio de direcciones virtuales.
- Si lanza un error de página al intentar acceder a una ubicación de memoria que no está configurada en las asignaciones de memoria virtual, obtiene una Señal de violación de segmentación (SIGSEGV), que normalmente es fatal.
- A medida que el sistema se queda sin RAM física, las páginas de RAM se eliminan; si son copias de solo lectura de algo que ya está en el disco (como un ejecutable o un archivo de objeto compartido), simplemente se desasignan y se vuelven a cargar desde su origen; si son de lectura-escritura (como la memoria que "creó" usando
malloc
), se escriben en el (archivo de página = archivo de intercambio = partición de intercambio = memoria virtual en disco). El acceso a estas páginas "liberadas" causa otra falla de página y se vuelven a cargar.
Generalmente, hasta que su proceso sea más grande que la RAM disponible -y los datos son casi siempre significativamente más grandes que el ejecutable- puede pretender que está solo en el mundo y ninguno de estos buscapersonas es sucediendo.
Entonces, efectivamente, el kernel es que ejecuta su programa mientras se está cargando (y puede que nunca cargue algunas páginas, si nunca se lanza a ese código/se refieren a esos datos).
Si su inicio es particularmente lento, puede mirar el sistema prelink
para optimizar las cargas compartidas de la biblioteca. Esto reduce la cantidad de trabajo que ld.so
tiene que hacer al inicio (entre el exec
de su programa y el main
recibiendo llamadas, así como cuando llama por primera vez a las rutinas de la biblioteca).
En ocasiones, enlazar estáticamente puede mejorar el rendimiento de un programa, pero con un gasto importante de RAM: dado que sus bibliotecas no se comparten, está duplicando "su libc
" además del libc
compartido que cada otro programa usando, por ejemplo. En general, esto solo es útil en sistemas integrados en los que su programa se ejecuta más o menos solo en la máquina.
(*) En realidad, el núcleo es un poco más inteligente, y por lo general se precarga algunas páginas para reducir el número de fallos de página, pero la teoría es la misma, independientemente de las optimizaciones
El OS normalmente trata esto de una manera sensata. –
100MB ¿binario imposible? Tengo aquí un binario de 6MB compilado a partir de un único programa de 500 CLO, fuertemente estructurado y potenciado en C++. Apuesto a que podría subir eso a 100MB sin demasiados problemas. –
¡Nada es imposible! Simplemente póngase en contacto con un feliz desarrollador de Eclipse, ellos le enseñarán todos los trucos. – Lundin