1. Qué puedes demostrar al terminar
Terminar el curso significa poder explicar un mecanismo, aplicarlo a un caso y comprobarlo con evidencia. La lista siguiente sirve para revisar capacidades concretas; si alguna requiere ayuda, los enlaces permiten volver al punto adecuado.
| Capacidad | Evidencia que puedes producir | Temas para revisar |
|---|---|---|
| Interpretar el espacio de un proceso | Relacionar código, datos, pila, heap y regiones con sus direcciones y permisos | 3, 4 y 5 |
| Administrar objetos en C | Justificar la propiedad de cada reserva y detectar accesos fuera de su vida útil | 7 y 9 |
| Traducir y proteger | Resolver direcciones con tablas y distinguir ausencia de permisos insuficientes | 19, 20 y 42 |
| Analizar rendimiento de memoria | Separar caché, TLB, fallos, conjunto de trabajo y ubicación NUMA | 26, 33 y 44 |
| Mapear y compartir | Elegir permisos, tipo de mapeo y protocolo de sincronización | 41 a 43 |
| Medir sin mezclar magnitudes | Registrar bytes útiles, residencia, compartición y picos con sus límites | 48 y 49 |
| Construir y verificar modelos | Presentar trazas, invariantes y casos de fallo de los dos proyectos | 50 y 51 |
Una salida correcta aislada es un comienzo. Una explicación más sólida indica qué se mantuvo fijo, qué se modificó y qué resultado habría refutado la hipótesis. Ese hábito sirve tanto al estudiar un simulador como al investigar un proceso real.
2. El mapa del curso, conectado
Los once bloques respondieron preguntas relacionadas. Esta tabla permite recuperar el recorrido completo sin convertirlo en una lista de definiciones desconectadas:
| Bloque y temas | Pregunta central | Conexión con el resto |
|---|---|---|
| 1 · 1–5 | ¿Qué direcciones ve el programa y por qué necesita aislamiento? | Da sentido a la traducción y la protección |
| 2 · 6–10 | ¿Cuánto viven los objetos y cómo se administran pila y heap? | Define qué accesos son correctos antes de estudiar páginas |
| 3 · 11–14 | ¿Cómo repartir intervalos y qué huecos quedan? | Introduce decisiones de asignación y fragmentación |
| 4 · 15–17 | ¿Cómo organizar regiones lógicas con límites y permisos? | Conecta estructura del programa, traducción y protección |
| 5 · 18–23 | ¿Cómo separar páginas virtuales de marcos físicos? | Hace posible ubicar páginas sin exigir contigüidad física del proceso entero |
| 6 · 24–27 | ¿Cómo reducir el costo de traducir y acceder? | Introduce TLB, tiempo efectivo y localidad |
| 7 · 28–33 | ¿Qué ocurre si una página válida no está residente? | Conecta demanda, fallos, copy-on-write y conjunto de trabajo |
| 8 · 34–39 | ¿Qué página se expulsa cuando no hay un marco libre? | Compara políticas y el costo de malas decisiones |
| 9 · 40–44 | ¿Qué respalda las páginas y cómo se mapean o comparten? | Une RAM, swap, archivos, permisos y ubicación física |
| 10 · 45–49 | ¿Cómo se reparten bloques de usuario dentro de regiones? | Explica malloc, fragmentación, asignadores y mediciones |
| 11 · 50–52 | ¿Cómo integrar, probar y explicar lo construido? | Convierte los mecanismos en proyectos reproducibles |
Los mismos términos pueden pertenecer a capas distintas. Un bloque de malloc no es una página; una caché de datos no es la TLB; un hueco del asignador no es necesariamente un marco libre del sistema.
3. Seguir un dato a través de las capas
Supón que un programa reserva un arreglo y escribe en su elemento número 1000. Podemos explicar el recorrido sin atribuir a una única función todo el trabajo:
- La aplicación define el objeto. Solicita un tamaño suficiente, conserva el puntero y respeta sus límites y vida útil.
- El asignador entrega un bloque. Puede reutilizar espacio administrado o necesitar obtener otra región del sistema.
- La instrucción usa una dirección virtual. El índice se transforma en un desplazamiento según el tipo del arreglo.
- La traducción y los permisos determinan el acceso. La TLB puede recordar la traducción; si no, intervienen las tablas y los mecanismos de la arquitectura.
- Una ausencia válida puede resolverse. El núcleo materializa o trae el respaldo necesario y reanuda la operación.
- La jerarquía atiende el dato. Cachés y memoria física influyen en el costo; no todo acceso llega hasta DRAM.
- La liberación termina la vida del objeto. El asignador puede conservar espacio para reutilizarlo sin retirar de inmediato toda la región.
La MMU no conoce los límites de cada objeto pequeño de malloc. Si un desbordamiento cae dentro de otra parte accesible de la misma página, el acceso puede completarse y aun así ser incorrecto en C. Protección por páginas y corrección de objetos se complementan.
Tampoco hay que interpretar «todo fallo lo resuelve el núcleo» como una promesa de acceso: una dirección no mapeada o una escritura prohibida puede provocar una señal en lugar de crear almacenamiento autorizado.
4. Tres cálculos que conviene conservar
4.1. Traducir una dirección
Con páginas de 4096 bytes y dirección virtual 10 000, la página es 2 y el desplazamiento 1808. Si la tabla la ubica en el marco 7:
10000 = 2 × 4096 + 1808
Física = 7 × 4096 + 1808 = 30480
El desplazamiento no cambia al traducir.
4.2. Comparar rutas con TLB
En un modelo sin fallos de página, con 110 ns por hit, 160 por miss resuelto en tabla y 99 % de hits:
Tiempo medio = 0.99 × 110 + 0.01 × 160 = 110.5 ns
Si aparecen fallos de página hay otra ruta y otro costo. No se puede aplicar esta media como si ya incluyera cargar desde un dispositivo, escribir una víctima o resolver una protección. El proyecto de memoria virtual hace explícitos sus eventos y evita contarlos dos veces.
4.3. Distinguir suma residente y costo proporcional
Dos procesos con 10 MiB privados cada uno y los mismos 20 MiB residentes compartidos tienen 30 MiB de RSS por proceso, pero 20 MiB de PSS por proceso en el modelo ideal. La suma de RSS es 60 y la de PSS es 40, que coincide con el contenido residente distinto de ese ejemplo.
La coincidencia requiere incluir a todos los usuarios y omite costos ajenos al modelo. No convierte PSS en memoria útil de objetos ni en contabilidad total del núcleo.
5. Distinciones que evitan diagnósticos erróneos
| Dos conceptos | La diferencia que debes poder explicar |
|---|---|
| Miss de TLB y fallo de página | Olvidar una traducción no implica que el contenido esté ausente de RAM |
| Dirección inválida y página válida ausente | La ausencia puede resolverse; no concede permisos a una dirección ajena |
| Copy-on-write y memoria compartida modificable | Una escritura privada puede crear una copia; no publica cambios como un mapeo compartido |
| Caché de páginas y swap | Un archivo limpio puede respaldar una recarga; los datos anónimos modificados necesitan conservar su propio contenido |
| Bloque libre y página devuelta | Reutilizar un objeto liberado no requiere que desaparezca su mapeo |
| RSS actual y máximo histórico | Un máximo no baja porque termine una fase que usó mucha RAM |
| Compartición y sincronización | Acceder al mismo contenido no vuelve atómica una actualización compuesta |
| Visibilidad y durabilidad | Que un lector vea bytes no demuestra que sobrevivan a una caída |
Estas distinciones permiten formular una prueba. Si sospechas fallos de página, mide sus eventos; si sospechas retención, contrasta objetos vivos y estructura del asignador; si sospechas una carrera, revisa la transferencia de propiedad y las operaciones concurrentes.
6. Caso integrador: un servicio que conserva memoria
Un servicio reserva 8 MiB de objetos temporales durante una petición. Al terminar conserva 512 KiB útiles y su RSS no vuelve al valor inicial. Además, la primera ejecución sobre un archivo grande tarda más que las siguientes. ¿Qué puedes concluir?
Los datos observados justifican preguntas, no una causa única. La reserva de 8 MiB no implica que esos bytes residieran todos al mismo tiempo; la reducción de objetos vivos no exige que el asignador retire todas sus regiones; y la diferencia entre lecturas puede estar influida por la caché de páginas.
- Registrar objetos vivos. Comprobar qué continúa siendo necesario y si se perdió la posibilidad de liberar alguna reserva.
- Separar métricas. Tomar valores actuales de RSS y PSS y conservar aparte el pico, con una fase y PID identificables.
- Inspeccionar regiones y asignador. Relacionar mapas y estadísticas compatibles con la biblioteca efectiva.
- Cambiar un patrón controlado. Comparar supervivientes dispersos y agrupados como en el tema 48, con la misma cantidad útil.
- Separar la lectura del archivo. Repetir y registrar condiciones, fallos y actividad pertinente sin llamar «disco» a toda espera.
Una evidencia de retención no elimina la posibilidad de una fuga en otro sitio. Y un archivo leído desde caché tampoco es una copia privada completa del proceso: las relaciones entre mapas y respaldo siguen siendo las del sistema de memoria.
Una propuesta de cambio debe indicar qué mecanismo intenta mejorar y qué costo puede trasladar. Reducir cachés del asignador puede bajar retención y aumentar trabajo posterior; separar vidas útiles puede vaciar regiones y también crear reservas sobredimensionadas.
7. Revisar los dos proyectos finales
Los proyectos son la evidencia práctica del recorrido. La revisión debe hacerse desde una inicialización limpia, con entradas guardadas y resultados que otra persona pueda reproducir.
7.1. Simulador de memoria virtual
Para el tema 50, conserva la configuración, la traza y las filas completas. Debe distinguir misses de TLB de fallos, actualizar referencia y suciedad también en hits e invalidar traducciones al expulsar.
$ ./memoria_virtual 3 2 lru traza.txt
$ ./memoria_virtual 3 0 lru traza.txt
$ ./memoria_virtual 3 2 reloj traza.txt
Al cambiar solo la TLB, las políticas de páginas del modelo deben seguir observando todos los accesos y conservar su cuenta de fallos. Al cambiar el reemplazo pueden variar víctimas, escrituras y costo. Un resultado diferente debe poder explicarse fila por fila.
7.2. Asignador con pruebas
Para el tema 51, conserva los tres archivos, opciones de compilación, semilla y cantidad de pasos. Incluye casos deterministas y estrés; comprueba bytes vivos además de enlaces y contadores.
$ gcc -std=c17 -Wall -Wextra -Wpedantic -O2 asignador.c pruebas.c -o pruebas
$ ./pruebas 12345 5000
$ ./pruebas 0 10000
$ ./pruebas 4294967295 10000
Los fallos previstos por agotamiento o fragmentación no son errores de la batería. Lo importante es que devuelvan el resultado definido sin alterar objetos vivos y que la limpieza final recupere una única región libre.
Si alguno falla, guarda el caso y redúcelo a una secuencia corta. No cambies expectativas para ocultar el fallo ni deduzcas rendimiento de una ejecución que dedica gran parte del tiempo a verificar todos los bytes.
8. Preparar un informe reproducible
Un cierre útil del curso es un informe breve que permita revisar un cálculo, una observación real y un proyecto. No necesita capturas de todas las pantallas: necesita datos suficientes para evaluar el razonamiento.
| Parte | Contenido mínimo |
|---|---|
| Entorno | Sistema, compilador, biblioteca relevante y opciones que afecten el experimento |
| Pregunta | Qué quieres comprobar y qué magnitud responde a esa pregunta |
| Entrada | Traza o patrón, tamaños, semilla y estado inicial |
| Resultado | Valores con unidades, fase y distinción entre actual, acumulado y máximo |
| Interpretación | Qué mecanismo es compatible con la evidencia y qué alternativas siguen abiertas |
| Prueba de corrección | Invariantes, casos límite y verificación de contenido cuando corresponda |
Incluye las limitaciones que realmente afectaron al resultado: un solo nodo NUMA, contadores no disponibles, un perfilador que modifica el asignador o una consulta denegada. Un dato no disponible no debe reemplazarse por cero.
En resultados de memoria, nombra explícitamente el ámbito. La suma de RSS de trabajadores, el PSS de un subconjunto y el consumo de un cgroup no tienen por qué coincidir aunque todos se expresen en MiB.
9. Un último programa: del mapeo al archivo
El punto de unión con el siguiente curso es un archivo mapeado. El programa crea un archivo nuevo, le da tamaño de una página, escribe un mensaje mediante MAP_SHARED y solicita sincronización. Después retira el mapeo, cierra el descriptor, vuelve a abrir el archivo y verifica los bytes mediante read.
Se exige un nombre que no exista: O_EXCL evita sobrescribir un archivo previo. El archivo queda como resultado de la práctica. Si una operación posterior a la creación falla, puede quedar un archivo parcial; el programa informa el fallo y no elimina rutas automáticamente.
#define _POSIX_C_SOURCE 200809L
#include <errno.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
int main(int argc, char *argv[])
{
if (argc != 2) { fprintf(stderr, "Uso: %s archivo_nuevo\n", argv[0]); return 1; }
const char mensaje[] = "De las paginas de memoria a los archivos";
long consulta = sysconf(_SC_PAGESIZE);
if (consulta <= 0 || (size_t) consulta < sizeof mensaje) {
fputs("Tamaño de página no utilizable\n", stderr); return 1;
}
size_t tam = (size_t) consulta;
int fd = open(argv[1], O_CREAT | O_EXCL | O_RDWR, 0600);
if (fd == -1) { perror("open crear"); return 1; }
if (ftruncate(fd, (off_t) tam) == -1) {
perror("ftruncate"); close(fd); return 1;
}
char *p = mmap(NULL, tam, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
if (p == MAP_FAILED) { perror("mmap"); close(fd); return 1; }
memcpy(p, mensaje, sizeof mensaje);
int error = 0;
if (msync(p, tam, MS_SYNC) == -1) { perror("msync"); error = 1; }
if (munmap(p, tam) == -1) { perror("munmap"); error = 1; }
p = NULL;
if (close(fd) == -1) { perror("close escritura"); error = 1; }
if (error) return 1;
fd = open(argv[1], O_RDONLY);
if (fd == -1) { perror("open lectura"); return 1; }
char leido[sizeof mensaje];
size_t recibidos = 0;
while (recibidos < sizeof leido) {
ssize_t n = read(fd, leido + recibidos, sizeof leido - recibidos);
if (n == -1) {
if (errno == EINTR) continue;
perror("read"); error = 1; break;
}
if (n == 0) { fputs("Fin de archivo antes del mensaje completo\n", stderr); error = 1; break; }
recibidos += (size_t) n;
}
if (close(fd) == -1) { perror("close lectura"); error = 1; }
if (error) return 1;
if (memcmp(leido, mensaje, sizeof mensaje) != 0) {
fputs("El contenido no coincide\n", stderr); return 1;
}
printf("Verificación correcta: %s\n", leido);
printf("Archivo creado: %s; tamaño: %zu bytes\n", argv[1], tam);
return 0;
}
$ gcc -std=c17 -Wall -Wextra -Wpedantic -O2 puente_archivo.c -o puente_archivo
$ ./puente_archivo prueba52.bin
Verificación correcta: De las paginas de memoria a los archivos
Archivo creado: prueba52.bin; tamaño: 4096 bytes
$ stat prueba52.bin
$ od -An -tx1 -N 48 prueba52.bin
4096 es el tamaño de página de un entorno posible. Si repites con el mismo nombre, la creación debe fallar y conservar el archivo existente; utiliza otro nombre para otra ejecución. No se necesita privilegio de administrador.
El tamaño del archivo se establece antes de mapear. El mensaje incluye el terminador cero, que se verifica antes de imprimirlo como cadena. El bucle de read contempla una lectura parcial, una interrupción y fin de archivo; estas reglas serán parte central del siguiente curso.
El ejemplo presupone que ningún otro proceso modifica o trunca el archivo durante la práctica. Haberlo releído con éxito comprueba el contenido visible en esa ejecución. No es una prueba de recuperación después de un corte de energía.
10. Visibilidad, sincronización y persistencia
El gestor de memoria explica cómo una región virtual se relaciona con páginas y respaldo. El sistema de archivos agrega nombres, metadatos, asignación en el dispositivo y reglas de consistencia. Son preguntas que se encuentran al modificar un archivo mapeado.
| Propiedad | Pregunta | Mecanismos pertinentes |
|---|---|---|
| Visibilidad | ¿Otro acceso puede observar los bytes nuevos? | Compartición y coherencia del contenido |
| Coordinación | ¿El lector observa un estado completo y autorizado? | Mutex, semáforos, atomics y protocolo de publicación |
| Sincronización con el archivo | ¿Se solicitó y esperó la actualización del intervalo mapeado? | msync con MS_SYNC y manejo de su resultado |
| Durabilidad y recuperación | ¿Qué contenido y nombres se recuperarán tras una caída? | Operaciones de sincronización y protocolo del sistema de archivos y del dispositivo |
msync con MS_SYNC solicita actualizar el contenido mapeado y espera su finalización. fsync sobre un descriptor aborda datos y metadatos del archivo; si importa la persistencia de un nombre recién creado o cambiado, también interviene el directorio. Un protocolo completo debe definir el orden de las operaciones y atender errores.
No necesitamos resolver aquí todos esos protocolos para comprender la frontera. Una lectura inmediata puede satisfacerse desde la caché de páginas. Por eso «cerré, abrí y vi el texto» no equivale a «demostré qué ocurrirá después de una caída».
Los detalles de estas interfaces pueden contrastarse en los manuales de mmap, msync y fsync. El curso siguiente desarrollará las preguntas de almacenamiento que estas llamadas abren.
11. Autoevaluación final
Responde sin abrir primero las explicaciones. Después pulsa Corregir para obtener un resultado por área y una ruta de repaso. Las preguntas evalúan criterios concretos; acompaña el resultado con los cálculos y proyectos anteriores.
Autoevaluación · 12 situaciones del curso
Todavía no se corrigieron las respuestas.
| Área | Respondidas | Correctas |
|---|---|---|
| Completa la autoevaluación y pulsa Corregir. | ||
Repaso sugerido según tus respuestas:
- La ruta se mostrará al corregir; también puedes usar la tabla siguiente.
12. Ruta de repaso según la dificultad
Utiliza una dificultad concreta para elegir la práctica, en lugar de releer sin objetivo. Después repite una variante nueva y explica el resultado antes de ejecutarla.
| Si cuesta… | Revisar | Práctica de recuperación |
|---|---|---|
| Separar página, offset y marco | Traducción de direcciones y simulador de paginación | Resolver tres direcciones, incluida una frontera de página |
| Interpretar un miss o un permiso | TLB, fallo de página y mprotect | Distinguir miss residente, carga válida y escritura prohibida |
| Explicar cambios privados o expulsiones | Copy-on-write, reemplazo y swap | Justificar qué copia se modifica y qué respaldo conserva cada víctima |
| Relacionar bloques y regiones | brk y mmap, lista libre y pruebas | Provocar un fallo por fragmentación y verificar que los datos vecinos sobreviven |
| Interpretar una cifra de memoria | fragmentación y mediciones | Registrar bytes útiles, RSS, PSS y pico por separado en dos fases |
| Relacionar compartir, cerrar y persistir | mmap de archivos y memoria compartida | Explicar quién posee cada recurso y cuándo se puede observar o conservar un cambio |
Si respondiste correctamente, revisa una evidencia diferente: una explicación oral, una traza nueva o una prueba negativa. Reconocer una opción correcta y detectar un error en un programa son habilidades relacionadas, pero requieren ejercicios distintos.
13. Cómo continúa en Sistemas de Archivos y E/S
La siguiente etapa de la ruta es el curso 9: Sistemas de Archivos y Entrada/Salida. La memoria ya nos dio las bases para preguntar qué se mantiene en caché, qué significa una página sucia y qué puede pasar cuando se retira un respaldo.
| Lo que traes de este curso | Pregunta que continúa | Entrada al próximo curso |
|---|---|---|
| Bytes y regiones de un archivo mapeado | ¿Cómo se relacionan ruta, descriptor y objeto del núcleo? | Tema 4 del programa: descriptores y tablas del kernel |
| Acceso a memoria y copia de bytes | ¿Cómo se manejan read, write, retornos parciales y posiciones? | Tema 6 del programa: read y write |
| Caché de páginas y localidad | ¿Por qué una lectura fría difiere de una caliente y cómo interviene la anticipación? | Tema 12 del programa: caché de páginas |
| Suciedad y escritura diferida | ¿Cuándo llega el contenido al almacenamiento y qué sincronización se necesita? | Temas 14 y 15 del programa: escritura diferida y fsync |
| Asignación de espacio y metadatos | ¿Cómo se organizan archivos, inodos, directorios y bloques? | Tema 17 del programa: volumen e inodo |
Esos enlaces muestran conexiones; la secuencia recomendada empieza por por qué se necesita un sistema de archivos. Allí se construirá el modelo de nombres, objetos persistentes y dispositivos antes de profundizar en cada llamada.
La unidad de protección y traducción que estudiamos fue la página; en almacenamiento aparecerán bloques, estructuras de metadatos y operaciones con su propia granularidad. Que dos unidades tengan el mismo tamaño en una máquina no significa que representen lo mismo.
La comunicación entre procesos mediante otras abstracciones continuará en la etapa siguiente de la ruta. Haber usado memoria compartida no obliga a resolver toda comunicación como un arreglo común: tuberías, colas y protocolos responden a otras necesidades.
14. Preguntas abiertas de cierre
Estas preguntas se responden mejor con una explicación y un ejemplo propio. Abre la orientación después de intentar formularla.
1. ¿Cómo explicarías malloc sin atribuirle todo el trabajo del sistema operativo?
Separando la reserva y reutilización de bloques de la gestión de regiones y páginas. Un malloc puede resolverse dentro de una región existente sin una llamada nueva al núcleo, mientras que un acceso posterior puede materializar respaldo.
2. ¿Por qué una dirección idéntica en dos procesos no demuestra que compartan datos?
Porque es una dirección virtual interpretada mediante el espacio de cada proceso. La compartición depende de sus mapeos y respaldo, no de que el número impreso coincida.
3. ¿Cómo demostrarías que un miss no implica E/S?
Con una traza donde la TLB olvida una traducción y la tabla conserva la página presente. En una ejecución real deben elegirse herramientas apropiadas y evitar confundir contadores de traducción con fallos mayores.
4. ¿Por qué mejorar la TLB no corrige toda lentitud de memoria?
Porque siguen importando las cachés de datos, el ancho de banda, los fallos de página, la contención y la ubicación NUMA. La mejora debe relacionarse con el cuello de botella observado.
5. ¿Cuándo puede bajar el RSS sin desaparecer una región?
Cuando se retira respaldo residente de una región que continúa mapeada, por ejemplo mediante un descarte apropiado. Hay que considerar si esa operación conserva o pierde contenido y qué ocurrirá al volver a acceder.
6. ¿Qué aporta una prueba negativa del asignador?
Demuestra que una comprobación rechaza un estado o resultado incorrecto concreto. El laboratorio del tema 51 altera un byte vivo para comprobar el detector; eso no significa que detecte todos los errores posibles.
7. ¿Qué evidencia te haría desconfiar de un simulador aparentemente correcto?
Un hit de TLB sobre una página ausente, una dirección física con otro offset, un bloque libre enlazado dos veces o contadores incompatibles. Las invariantes permiten encontrar esos problemas aunque el programa no se caiga.
8. ¿Qué ha probado el programa puente al releer el mensaje?
Que los bytes escritos mediante el mapeo se observaron mediante la lectura del archivo en esa ejecución, después de comprobar las operaciones. No ha ensayado una caída ni validado por sí solo un protocolo de recuperación y persistencia del nombre.
15. Con qué continuar
Conserva tres resultados: una explicación del recorrido de una dirección, un informe de medición con magnitudes bien definidas y los dos proyectos con sus pruebas. Juntos muestran comprensión de los mecanismos, capacidad de observarlos y criterio para verificar una implementación.
- Una dirección virtual necesita un contexto de traducción y protección.
- La disponibilidad de memoria depende de regiones, páginas, respaldo y demanda.
- El rendimiento requiere localidad y una interpretación correcta de cada costo.
- Los bloques de usuario añaden otra capa de administración y vida útil.
- Las métricas y las pruebas deben corresponder a la pregunta que se intenta resolver.
- Los archivos conectan ese contenido con nombres, dispositivos y garantías de conservación.
Completaste el recorrido temático de Gestión de Memoria, paso 8 de la ruta de Sistemas Operativos. Puedes volver al índice para repasar o continuar desde el inicio de Sistemas de Archivos y Entrada/Salida.