10.1.2.2.2. Gestión de memoria

Antes de estudiar cómo gestiona el sistema operativo la memoria, es preciso recordar dos aspectos ya señalados:

  • La ejecución de todo programa supone que tanto su código como los datos que manipula se copien en la memoria RAM.

  • La memoria está dividida en celdas cuyo contenido constituye una palabra, por lo general de un byte, cada una de las cuales se referencia mediante una dirección de memoria única. Al total de la memoria se lo denomina espacio físico de memoria. Por ejemplo, para una memoria RAM de 16 MiB, el espacio de memoria va desde la dirección 0x000000 a la dirección 0xFFFFFF:

    ../../../../_images/espaciomemoria.png

El espacio físico de memoria está bastante limitado (la memoria RAM es cara), por lo que una labor muy importante del sistema operativo es gestionar cómo los procesos utilizarán esta memoria.

10.1.2.2.2.1. Ocupación de memoria

Al crear un proceso, sus necesidades de memoria son las siguientes:

  • Un PCB, cuyos metadatos requiere el sistema operativo para gestionarlo.

  • Un espacio virtual de memoria en el que se almacenan el código y los datos que manipula. Éste espacio virtual, a su vez, se compone de cuatro espacios:

    • Código, que es espacio reservado para las instrucciones del programa y que, obviamente, no varía a lo largo de la ejecución del proceso.

    • Datos, que se corresponden con los datos iniciales del programa y que, aunque puedan cambiar de valor, no cambian su tamaño.

    • Montículo, que contiene los datos que se creen dinámicamente durante la ejecución. Este espacio es dinámico y, por tanto, de tamaño variable durante la ejecución.

    • Pila, que contiene las llamadas anidadas a fragmentos distintos de código cada uno de los cuales tiene un contexto propio, esto es, un conjunto de datos distintos. Es necesario mantener la pila, porque un fragmento de código, sin haber terminado su ejecución, puede crear otro y pasar a ejecutar este. Como al terminar este segundo, se vuelve al primer fragmento, es necesario recordar por cuál instrucción iba la ejecución en el momento del salto y cuáles eran los datos que se manejaban entonces. Este espacio también es variable: comienza no ocupando memoria y crece y decrece durante la ejecución según haya más o menos contextos anidados.

En este espacio virtual, cuya primera dirección siempre es 0x0 se colocan al principio el código y los datos, que tiene tamaño fijo; el monticulo, que al comienzo no tendrá ningún tamaño empieza a crecer a continuación y la pila, que también es variable, se coloca al final del espacio y empieza a crecer hacia direcciones virtuales de memoria más bajas.

../../../../_images/segmeprog.png

Estas direcciones virtuales son con las que trabaja internamente cada proceso. Ahora bien, estos datos deben estar almacenados, en realidad, en direcciones físicas de memoria, por lo que es necesario hacer una traducción entre estas direcciones virtuales y las direcciones físicas. La encargada de ello es una parte del procesador llamada Unidad de manejo de memoria (MMU por sus siglas en inglés).

10.1.2.2.2.2. Técnicas

Existen distintas técnicas para alojar los procesos en memoria.

10.1.2.2.2.2.1. Particiones

En esta solución la memoria se divide en bloques que ocupan direcciones contiguas de memoria física, a los que se denomina partición. Cada partición comienza en una dirección de memoria, que se denomina registro base y tiene un tamaño concreto que determina cuál es su registro límite. En esta técnica a cada proceso se le asigna una única partición y una partición sólo puede estar ocupada por un único proceso. El sistema operativo se encarga de mantener el registro de dónde comienza cada partición, cuánto tamaño tiene y qué proceso la está ocupando. Como todo proceso debe caber en un partición, esto obliga a que los espacios virtuales de memoria sean pequeños (como máximo el tamaño de la partición mayor).

El particionado puede ser de dos tipos:

Fijo

La memoria se particiona de antemano, de manera que las particiones son fijas, aunque no todas tienen por qué tener el mismo tamaño. Su principal desventaja es que los espacios virtuales de los procesos no casan en tamaño exactamente con las particiones, por lo que la parte de la partición que no haya sido ocupada por el proceso al que se le ha asignado, no puede aprovecharse. Esta circunstancia se denomina fragmentación interna.

Dinámico

Las particiones se van creando ajustándose al tamaño de cada proceso. En este caso, no existe fragmentación interna, pero cuando un proceso acabe, se liberará la partición que tendrá el tamaño del proceso extinto. Como un nuevo proceso es probable que requiera un tamaño distinto, quedan entonces también huecos de memoria entre particiones sin utilizar. En este caso se habla de fragmentación externa.

10.1.2.2.2.2.2. Paginación

En la técnica de las particiones cada proceso ocupa siempre direcciones de memoria contiguas. La paginación, en cambio, no exige eso. En ella, el sistema operativo divide el espacio de memoria física en bloques de tamaño fijo, a los que se denomina frames, y el espacio virtual de memoria de cada proceso en bloques llamados páginas que tienen el mismo tamaño que los frames. Tanto páginas como frames se numeran correlativamente.

La técnica consiste en asociar a cada página un frame distinto, pero sin la necesidad de que a las páginas de un proceso se le asignen frames contiguos. Para ello el sistema operativo crea para cada proceso una tabla de paginación que lleva el control de estas asignaciones. En el PCB deberá existir un puntero a la correspondiente tabla de paginación.

La técnica sigue produciendo fragmentación interna, pero en mucha menor medida que la técnica de particiones fijas.

10.1.2.2.2.2.3. Segmentación

Esta técnica consiste en fragmentar el espacio virtual de memoria en bloques, llamados segmentos (que no tienen que tener igual tamaño) dentro de los cuales se almacena información que comparta algo en común. Estos segmentos se asignan a espacio en la memoria física que no tiene que ser contiguo, de manera que el sistema operativo irá buscando huecos libres para ubicarlos.

El sistema operativo debe crear para cada proceso una tabla con todos los segmentos de los que se compone indicando qué dirección física ocupa y cuál es su tamaño. Esta técnica, como la de particiones dinámicas presenta fragmentación externa, pero en mucha menor medida.

10.1.2.2.2.2.4. Memoria virtual

Esta técnica, que se compagina con la de paginación o segmentación, permite alojar en memoria RAM no todo el proceso, sino sólo las páginas o segmentos del fragmento de código y los datos que se estén ejecutando; el resto se guarda en memoria secundaria y se rescata de ella, cuando se necesite.

Ahora bien, como la memoria secundaria es muchísimo más lenta, la memoria virtual sólo se usa en caso de que sea estrictamente necesario, esto es, cuando el proceso que se quiere cargar en memoria necesita más espacio de la memoria disponible. También es posible que el sistema decida que de otro proceso ya cargado en memoria RAM todo o parte pase a memoria virtual. Al volver a la memoria principal, no tendrá por qué ocupar las mismas direcciones de memorias.

La zona de la memoria secundaria que se usa como memoria de intercambio no es caprichosa, es una zona especial reservada para tal fin que se llama memoria de intercambio, memoria swap o, simplemente, swap. En los sistemas Windows se usa un fichero definido para tal fin; en los sistemas linux, aunque es posible el uso del fichero, es común, la creación de una partición especial en el disco duro dedicada exclusivamente a este fin.

Nota

Hacer demasiado uso de la memoria de intercambio penaliza el rendimiento, y es señal de que debemos ir pensando en aumentar la memoria RAM del equipo.