Capítulo 5: Gestión de la memoria principal

Publicado por P. Ruiz en

Paginación

En la Gestión de memoria con particiones variables, hemos visto que la memoria disponible tiende a no estar en posiciones contiguas, por lo que se produce una considerable fragmentación externa (la memoria disponible se dispersa a lo largo del espacio de direcciones.

Para resolver esta circunstancia, se planteó la posibilidad de que el espacio de memoria que usa un determinado proceso no tuviese que estar en posiciones contiguas. Así, en un esquema de paginación, la memoria se divide en trozos del mismo tamaño que reciben el nombre de marcos de página (o, en inglés, frames). Del mismo modo, los procesos se dividen en fragmentos del mismo tamaño denominados páginas.

A modo de ejemplo, imagina que el proceso que queremos cargar en memoria lo representáramos con el zumo contenido en la botella de la siguiente imagen. Por su parte, la memoria donde pretendemos almacenarlo estaría representada por los vasos. Cada vaso, sería el equivalente a un marco de página de la memoria.

Ejemplo 1

Así, cuando carguemos el proceso en memoria, cada página (cantidad de zumo del tamaño de un vaso) se ubicará en un marco de página diferente.

Ejemplo 2

De este modo, cuando llegue un nuevo proceso, el único problema será encontrar la cantidad suficiente de marcos de página disponibles en la memoria principal.

Gracias a este planteamiento, se acaba con la fragmentación externa, y la fragmentación interna quedará reducida al último marco de página asignado a cada proceso. Lo que equivaldría, en nuestro ejemplo, al último vaso.

Cabe esperar que, por término medio, la mitad del último marco de página quede desocupado.

Como podrás suponer, este esquema necesita un método que traduzca las direcciones virtuales a direcciones físicas, teniendo en cuenta la ubicación real de cada marco de página. Este método se basa en la creación de una tabla de páginas, para cada proceso, en el momento de cargarlo en memoria. En ella se establecerá el paralelismo entre cada página y su marco de página correspondiente.

Por lo tanto, las direcciones virtuales constarán de un número de página y un desplazamiento dentro de ella. El número de página actuará como índice en la tabla de páginas.

Además, es frecuente que el sistema operativo mantenga una lista de marcos de página disponibles.

Las direcciones virtuales también suelen llamarse direcciones relativas y suelen asignarse durante la compilación del programa, siendo relativas al comienzo del mismo (que será la dirección 0 de la página 0).

paginación

Dado que este método implica constantes traducciones de direcciones virtuales a direcciones físicas, para evitar que el sistema sufra una importante penalización de rendimiento, habrá que recurrir a un hardware específico para la traducción.

Por otra parte, el sistema operativo dispondrá de un mapa de la memoria, con una entrada por cada marco de página, donde se indique cuáles están libres y cuáles ocupados.

Ejemplo de paginación

Un ejemplo del funcionamiento de este método lo encontramos en el microprocesador Intel 8088 de los primeros ordenadores personales, aunque Intel utiliza el nombre segmento para referirse al concepto de página.

En el Intel 8088, los registros del procesador eran de 16 bits. Esto significaba que el registro de direcciones podía referenciar 216 (65,536) posiciones de memoria diferentes. Es decir, 64 KB.

Expresado en hexadecimal, los valores de direcciones válidos estarían entre 0000(16 y FFFF(16.

Sin  embargo, el bus de direcciones en aquellos ordenadores era de 20 bits, lo que nos permitiría un máximo de 220 (1,048,576) direcciones de memoria diferentes, que podrían expresarse con valores comprendidos entre 00000(16 y FFFFF(16.

Para conseguir aprovechar toda la capacidad del bus, las direcciones lógicas se representaron con dos valores de 16 bits: El de la izquierda representaba el desplazamiento y el de la derecha la página (o segmento en terminología Intel).

Por ejemplo, una dirección lógica válida sería: 1B3C:A23E

Para calcular la dirección física se realiza una operación llamada suma con desplazamiento, que consiste en añadirle un 0 al valor del desplazamiento (esto equivale a multiplicarlo por 16). A continuación, se le suma el valor de la página.

Para nuestro ejemplo, la operación sería 1B3C0(16 + A23E(16 = 255FE(16.

Por lo tanto, la dirección física sería 255FE.

Como hemos dicho al principio, los procesadores Intel 8088 disponían de registros, de 16 bits, donde guardar los valores de desplazamiento. Es decir, las direcciones dentro de una página. Además, tenían 4 registros, también de 16 bits, para identificar las páginas, que guardaban la dirección de la página activa en cada momento:

  • CS (Code segment), que tiene la dirección de la página con el programa que se está ejecutando.

  • DS (Data segment), con la dirección de la página de datos del programa que se está ejecutando.

  • SS (Stack segment), que  tiene la dirección de la página con la pila del programa.

  • ES (Extra segment), la dirección de una página auxiliar que puede usarse como complemento a cualquiera de los anteriores o para guardar de forma temporal direcciones intermedias.

En ocasiones, si el programa es pequeño, puede usar la misma página para todas las funciones.

Un aspecto a tener en cuenta será el tamaño de los marcos de página:

  • Con marcos de página pequeños, tendremos poca fragmentación interna y tablas de páginas grandes.

  • Con marcos de página grandes, tendremos más fragmentación interna y tablas de páginas pequeñas.

Usando la paginación, se pueden seguir aplicando técnicas de intercambio, para mover a memoria secundaria, los procesos que se encuentran bloqueados en espera de un suceso.

Otras consideraciones a tener en cuenta

Cuando se utilizan tablas de páginas de gran tamaño, puede que buena parte de las tablas de los procesos activos se encuentren descargados en memoria secundaria, perjudicando su rendimiento.

Además, el diseño de la memoria secundaria suele estar orientado al manejo de bloques grandes, que se adecuan mejor al uso de páginas de mayor tamaño.

Sin embargo, si utilizamos páginas pequeñas, cuando un proceso lleve un tiempo ejecutándose, todas sus páginas de memoria tendrán referencias con una alta probabilidad de ser utilizadas, lo que reducirá la tasa de fallos de página (ver el principio de cercanía, más adelante, en el apartado Gestión de Entrada/Salida).

En cualquier caso, el tamaño de página deberá estar relacionado con la cantidad de memoria principal y el uso que vayamos a hacer de ella. Por ejemplo, las técnicas de programación orientada a objetos produce programas con bloques de código pequeños que generan referencias a posiciones de memoria dispersas en breves periodos de tiempo. Por su parte, las aplicaciones multihilo suelen modificar bruscamente el flujo de referencias a instrucciones y datos.

Actividad 2: Gestión de memoria por paginación – 1

Supongamos un sistema operativo con las siguientes características:

  • La memoria se gestiona usando paginación.

  • Las páginas tienen un tamaño de 512 palabras

Si, en un momento determinado, un proceso hace referencia a la dirección 2805, responde a las siguientes cuestiones de forma razonada:

  1. ¿Qué página y desplazamiento corresponden a esa dirección?

  2. ¿La dirección lógica obtenida puede corresponder a la dirección física 6201?

  3. ¿Y a la dirección física 4853?

Actividad 3: Gestión de memoria por paginación – 2

Supongamos un sistema operativo con las siguientes características:

  • La arquitectura del sistema es de 64 bits.

  • La memoria se gestiona usando paginación.

  • Cada marco de página tiene un tamaño de 1024 palabras.

En el momento actual, el sistema tiene almacenados cuatro procesos con las siguientes tablas de páginas:

ejercicio 2

Partiendo de dicha información, debes realizar las siguientes tareas:

  1. Elaborar una tabla que represente la ocupación actual de la memoria (al estilo de la que aparece en la actividad siguiente)

  2. Calcular la capacidad de almacenamiento aproximada que estamos perdiendo por la fragmentación

  3. Razonar el tipo de fragmentación del que se trata.

Actividad 4: Gestión de memoria por paginación – 3

Supongamos un sistema operativo con las siguientes características:

  • La arquitectura del sistema es de 32 bits.

  • La memoria se gestiona usando paginación.

  • Cada marco de página tiene un tamaño de 512 palabras.

En el momento actual, el sistema tiene ocupados los marcos de página que podemos ver el la siguiente imagen.

Teniendo en cuenta que el contenido de cada marco indica el proceso al que se encuentra actualmente asignado y el número de página dentro de este, debemos resolver lo siguiente:

  1. Definir la composición actual de las tablas de páginas de los distintos procesos (al estilo de las que aparecían en la actividad anterior).

  2. Averiguar el tamaño máximo de proceso que podremos almacenar en la memoria sin liberar ninguno de los marcos de página ocupados actualmente.

  3. Calcular la dirección física que corresponde a cada proceso, cuando traten de acceder a la dirección lógica 2304.