4.3. Conceptos básicos sobre Memoria Virtual

Aún cuando la tecnología detrás de la construcción de las implementaciones modernas de almacenamiento es realmente impresionante, el administrador de sistemas promedio no necesita estar al tanto de los detalles. De hecho, solamente existe un factor que los administradores de sistemas deberían tener en consideración:

Nunca hay suficiente RAM.

Mientras que esta frase puede sonar al principio un poco cómica, muchos diseñadores de sistemas operativos han empleado una gran cantidad de tiempo tratando de reducir el impacto de esta limitación. Esto lo han logrado mediante la implementación de la memoria virtual — una forma de combinar RAM con un almacenamiento más lento para darle al sistema la apariencia de tener más RAM de la que tiene instalada realmente.

4.3.1. La memoria virtual en términos sencillos

Vamos a comenzar con una aplicación hipotética. El código de máquina que conforma esta aplicación tiene un tamaño de 10000 bytes. También requiere otros 5000 bytes para el almacenamiento de datos y para la memoria intermedia de E/S. Esto significa que para ejecutar la aplicación, deben haber más de 15000 bytes de RAM disponible; un byte menos y la aplicación no será capaz de ejecutarse.

Este requerimiento de 15000 bytes se conoce como el espacio de direcciones de la aplicación. Es el número de direcciones únicas necesarias para almacenar la aplicación y sus datos. En las primeras computadoras, la cantidad de RAM disponible tenía que ser mayor que el espacio de direcciones de la aplicación más grande a ejecutar; de lo contrario, la aplicación fallaría con un error de "memoria insuficiente".

Un enfoque posterior conocido como solapamiento intentó aliviar el problema permitiendo a los programadores dictar cuales partes de sus aplicaciones necesitaban estar residentes en memoria en cualquier momento dado. De esta forma, el código requerido solamente para propósitos de inicialización podía ser sobreescrito con código a utilizar posteriormente. Mientras que el solapamiento facilitó las limitaciones de memoria, era un proceso muy complejo y susceptible a errores. El solapamiento también fallaba en solucionar el problema de las limitaciones de memoria globales al sistema en tiempo de ejecución. En otras palabras, un programa con solapamiento requería menos memoria para ejecutarse que un programa sin solapamiento, pero si el sistema no tiene suficiente memoria para el programa solapado, el resultado final es el mismo — un error de falla de memoria.

Con la memoria virtual el concepto del espacio de direcciones de las aplicaciones toma un significado diferente. En vez de concentrarse en cuanta memoria necesita una aplicación para ejecutarse, un sistema operativo con memoria virtual continuamente trata de encontrar una respuesta a la pregunta "qué tan poca memoria necesita la aplicación para ejecutarse?".

Aunque inicialmente pareciera que nuestra aplicación hipotética requiere de un total de 15000 bytes para ejecutarse, recuerde nuestra discusión anterior en la Sección 4.1 — el acceso a memoria tiende a ser secuencial y localizado. Debido a esto, la cantidad de memoria requerida para ejecutar la aplicación en un momento dado es menos que 15000 bytes — usualmente mucho menos. Considere los tipos de accesos de memoria requeridos para ejecutar una instrucción de máquina sencilla:

El número real de bytes necesarios para cada acceso de memoria varían de acuerdo a la arquitectura del CPU, la instrucción misma y el tipo de dato. Sin embargo, aún si una instrucción requiere de 100 bytes de memoria por cada tipo de acceso de memoria, los 300 bytes requeridos son mucho menos que el espacio de direcciones total de la aplicación de 15000 bytes. Si hubiese una forma de hacer un seguimiento de los requerimientos de memoria de la aplicación a medida que esta se ejecuta, sería posible mantener la aplicación ejecutándose usando menos memoria que lo que indicaría su espacio de direcciones.

Pero esto genera una pregunta:

Si solamente una parte de la aplicación está en memoria en un momento dado, dónde esta el resto?

4.3.2. Almacenamiento de respaldo — el Tenet central de la memoria virtual

La respuesta corta a esta pregunta es que el resto de la aplicación se mantiene en disco. En otras palabras, el disco actúa como un almacenamiento de respaldo para la RAM; un medio más lento y también más grande que actúa como un "respaldo" para un almacenamiento más rápido y más pequeño. Esto puede parecer al principio como un gran problema de rendimiento en su creación — después de todo, las unidades de disco son mucho más lentas que la RAM.

Aunque esto es cierto, es posible tomar ventaja del comportamiento de acceso secuencial y localizado de las aplicaciones y eliminar la mayoría de las implicaciones de rendimiento en el uso de unidades de disco como unidades de respaldo para la RAM. Esto se logra estructurando el subsistema de memoria virtual para que este trate de asegurarse de que esas partes de la aplicación que actualmente se necesitan — o que probablemente se necesitaran en un futuro cercano — se mantengan en RAM solamente por el tiempo en que son realmente requeridas.

En muchos aspectos, esto es similar a la situación entre la caché y la RAM: haciendo parecer una poca cantidad de almacenamiento rápido con grandes cantidades de un almacenamiento lento actuar como que si se tratase de grandes cantidades de almacenamiento rápido.

Con esto en mente, exploremos el proceso en más detalle.