Sistemas Operativos: Administrador de la memoria RAM, métodos y algoritmos.
GESTION DE MEMORIA
El desempeño de los sistemas de computadoras ha
sido directamente dependiente de dos cosas: Cuánta memoria hay disponible en la computadora. Cómo se administra la memoria disponible a medida que se procesan los programas. Introducción En los sistemas operativos originales existían cuatro tipos de esquemas para la asignación de memoria (memory allocation) a los trabajos (jobs): Esquema original o de espacio continuo Particiones fijas Particiones dinámicas Particiones dinámicas relocalizables En esta presentación se utilizarán los términos programa y trabajo como si fuesen sinónimos. Esquema original ó de espacio continuo En los sistemas de computadoras originales (fines de los 1940s y principios de los 1950s) el esquema de asignación de memoria era bien simple. Cada programa que se quería procesar se cargaba enteramente a memoria (RAM) y se le asignaba todo el espacio que necesitara de forma continua. El esquema de espacio continuo (contiguous scheme) presenta un grave problema: Si el programa no cabe en RAM completamente y de forma continua, NO se puede ejecutar. Además sólo se cargaba un programa a la vez. Esquema original ó de espacio continuo Los sistemas operativos uniusuario (uniuser) para microcomputadoras Sistema Operativo como DOS trabajaban de forma similar: Aplicación Se cargaba todo el s.o a RAM. Luego se cargaba la aplicación deseada y se ejecutaba. Espacio libre El espacio sobrante era inutilizable ya que sólo una aplicación podía estar en RAM. Particiones Fijas Los mainframes originales usaron s.o. en lote y la multiprogramación para poder cargar varias aplicaciones a memoria. En el esquema de particiones fijas (fixed partitions) a cada programa se le asignaba un espacio en memoria (la partición). No todas las particiones deben tener el mismo tamaño pero el tamaño de la partición era fijo. Este esquema, también conocido como particiones estáticas (static partitions) es más flexible que el esquema original porque permite más de un programa en memoria a la vez. Desventajas: Sin embargo, todavía se requiere que el programa quepa completo y de forma continua en alguna partición. Particiones Fijas Un problema del esquema de particiones fijas es que el operador del sistema debe decidir el tamaño de las particiones antes de cargar los programas. Esto muchas veces causa una fragmentación interna (internal fragmentation) que surge cuando se carga un programa en una partición demasiado grande y se desperdicia espacio. Particiones Dinámicas En el esquema de las particiones dinámicas (dynamic parititions) se le da a cada trabajo sólo la cantidad de memoria que necesita. No se desperdicia memoria en las particiones pero todavía se crea un problema cuando se administra la memoria que deja un programa que haya finalizado Particiones Dinámicas Cuando los trabajos originales llegan, no hay memoria desperdiciada. ¿Qué ocurre cuando se sacan trabajos de memoria y llegan nuevos trabajos que no son del mismo tamaño que el espacio que quedó vacante? Se crean espacios libres de memoria no utilizados entre las particiones. Esto se conoce como fragmentación externa. Particiones Dinámicas Particiones Dinámicas Conclusión Los esquemas discutidos en este capítulo para la administración de la memoria tienen tres cosas en común: 1. Requieren que el programa sea cargado completamente en memoria. 2. Requieren que el programa esté almacenado de forma continua. 3. Requieren que el programa permanezca en memoria hasta que haya acabado. Conclusión Estos esquemas eran válidos para las primeras generaciones de computadoras en los que los programas (trabajos) se procesaban en lote. A fines de los 1960s y principios de los 1970s surgió la necesidad de que las computadoras atendieran interactivamente a varios usuarios a la vez. Administración de la memoria virtual Los esquemas de administración de memoria que se discutirán en la próxima lección tienen dos cosas en común: Los programas no tienen que estar almacenados en localizaciones continuas de memoria (se pueden dividir en porciones). No es necesario mantener todas las porciones del programa en memoria principal todo el tiempo. Asignación paginada de memoria En el esquema de asignación paginada de memoria (paged memory allocation) el programa que se carga a memoria se divide en porciones del mismo tamaño llamadas páginas. Estas páginas no tienen que ser colocadas de forma continua en memoria. Pero todas las páginas deben ser cargadas antes de ejecutar el programa. La mayoría de los s.o. escogen un tamaño de página que sea igual al tamaño de un sector (bloque) de disco. Esto se hace para que cada página sea cargada con una sola operación de lectura de disco. Asignación paginada de memoria La memoria, a su vez, se divide en porciones del mismo tamaño de los sectores de disco llamadas marcos de página (page frames). Por lo tanto, Un sector de disco contendrá Una página de instrucciones que cabrá en Un marco de página de memoria primaria
Antes de ejecutar un programa el Administrador de la Memoria:
1. Determina la cantidad de páginas en el programa. 2. Localiza los marcos de página en la memoria primaria. 3. Carga todas las páginas a sus respectivos marcos. Asignación paginada de memoria El mapa de memoria de cada proceso se considera dividido en páginas. A su vez, la memoria principal del sistema se considera dividida en zonas del mismo tamaño que se denominan marcos de página. Un marco de página contendrá en un determinado instante una página de memoria de un proceso. Todo el programa es cargado en memoria. Asignación paginada de memoria Tabla de páginas: es la estructura de datos que relaciona cada página con el marco donde está almacenada. Tabla de Marcos de página: Es una estructura para almacenar el estado de ocupación de la memoria principal y que permite conocer qué marcos están libres y cuáles están ocupados. Tabla de regiones: Contiene las características de cada región especificando qué rango de páginas pertenecen a la misma. Fragmentación Interna Observe que con la paginación se le asigna a cada proceso un número entero de marcos de página, aunque, en general, su mapa no tendrá un tamaño múltiplo del tamaño del marco. Por tanto, se desperdiciará parte del último marco asignado al proceso, lo que correspondería con las zonas sombreadas que aparecen en la siguiente figura. A este fenómeno se le denomina fragmentación interna e implica que por cada proceso de desperdiciará, en término medio, la mitad de una página, lo cual es un valor bastante tolerable. Paginación por demanda La paginación por demanda (demand paging) permite cargar sólo una parte del programa en memoria. En este esquema el programa sigue dividiéndose en porciones de tamaño fijo (páginas) que inicialmente residen en memoria secundaria. Estas páginas sólo se cargan cuando sea necesario. La clave de la paginación por demanda requiere un acceso de alta velocidad a las páginas que están en disco. Este esquema hizo viable la memoria virtual (virtual memory) ya que permite dar la apariencia de tener disponible una cantidad ilimitada de memoria al utilizar parte de la memoria secundaria como resguardo de la memoria primaria. Segmentación En el esquema de asignación segmentada de memoria (segmented memory allocation), cada programa se divide en varios bloques de longitud variable a los cuales se les llamará segmentos . Muchas veces el criterio es segmentar el programa por módulos o subrutinas. Esto reduce las fallas de página que resultan de tener código relacionado que distribuido en más de una página. Cuando se usa la segmentación, la memoria principal ya no se divide en marcos de página sino que se asigna dinámicamente. Segmentación La tabla de correspondencia de segmentos (Segment Map Table o SMT) es creada para cada programa. El SMT contiene: El número de cada segmento Su tamaño Bits de estatus (presencia en memoria), referencia y modificación Derechos de acceso (lectura, escritura, ejecución) Localización en memoria Segmentación El esquema de segmentación permite que los segmentos no estén colocados de forma continua en memoria principal y que sólo se carguen a medida de que se necesitan (de acuerdo a la demanda). Paginación y Segmentación Segmentación Paginada El esquema de asignación segmentada y paginada por demanda (segmented/demand paged memory allocation) divide lógicamente el programa en segmentos de distinto tamaño que forman grupos relacionados de instrucciones (subrutinas). Pero estos segmentos son divididos físicamente en páginas de tamaño fijo para su manipulación eficiente. No todas las páginas de un segmento tienen que estar en memoria a la vez. Segmentación Paginada La mayor desventaja de este esquema es el esfuerzo extra (overhead) que se requiere para la manipulación de las tablas y el tiempo que requiere buscar una localización de memoria. Muchos sistemas usan memoria asociativa para acelerar este proceso. Memoria Virtual Los esquemas de paginación y segmentación por demanda hacen posible tratar una porción de la memoria secundaria como si fuera parte de la memoria principal. A esta porción se le conoce como memoria virtual. El uso de la memoria virtual requiere la cooperación constante del Administrador de la Memoria (que determina dónde está cada página o segmente) y el CPU (que genera interrupciones en caso de intentos fallidos en el acceso de páginas y ayuda en la resolución de direcciones). Paginación por demanda Si no hay marcos disponibles, el s.o. determina cuál marco debe vacíar para hacer espacio para la página. En caso de que el marco contenga una página que ha sido modificada, se genera una interrupción y hay que pasar la copia modificada a disco antes de cargar la nueva página de disco a memoria. Este proceso se conoce como intercambio (swapping). Si hay una cantidad excesiva de intercambios de página entre la memoria principal y el almacenamiento secundario, ocurre lo que se conoce como azote (thrashing). La razón principal de los azotes es tener una gran cantidad de programas compitiendo por una pequeña cantidad de marcos en memoria. Page Fault (Fallos de página) Políticas de Reemplazo Como hemos visto, cuando todos los marcos están ocupados y se tiene que cargar una página a memoria, se debe seleccionar cuál de las páginas que ya están cargadas debe reemplazarse. Esta decisión es crucial para la eficiencia del sistema. Existen varios algoritmos para remoción de páginas Políticas de Reemplazo Se clasifican en dos categorías: REEMPLAZO GLOBAL Y REEMPLAZO LOCAL. Ambas estrategias son utilizadas para satisfacer un fallo de página.
• Reemplazo Global: Con una estrategia de reemplazo
global se puede seleccionar un marco que actualmente tenga asociada una página de otro proceso. Políticas de Reemplazo: Algorítmo Óptimo La política del reemplazo óptimo (optimal replacement) selecciona para reemplazo aquella página que tardará más tiempo en ser referenciada en el futuro. Esta política es la mejor teóricamente pero es imposible de implementar ya que requiere que el s.o. sea clarividente. El interés de este algoritmo es que sirve para comparar el rendimiento de otros algoritmos. First in- First Out, FIFO La política de que la primera página que llegó es la primera que sale En esta cola las páginas siempre se añaden al final, por lo que la página que más tiempo lleve cargada estará al inicio de la cola. Cuando hay que remover una página, el s.o. simplemente selecciona la primera página en la cola. Este algoritmo no toma en consideración cuántas veces ha sido referenciada la página que se selecciona para remoción. Algoritmo de la segunda oportunidad Cuando se necesita reemplazar una página, se examina el bit de referencia de la página más antigua (la primera de la lista). Si no está activo, se usa esta página para el reemplazo. En caso contrario, se le da una segunda oportunidad a la página poniéndola al final de la lista y desactivando su bit de referencia. Por tanto, se la considera como si acabara de llegar a memoria. La búsqueda continuará hasta que se encuentre una página con su bit de referencia desactivado. Página menos usada recientemente La política de remoción de la página menos usada recientemiente (least recently used, LRU) parte de la premisa que aquellas páginas que han sido usadas frecuentemente por las últimas instrucciones ejecutadas serán también usadas frecuentemente por las próximas instrucciones que se ejecutarán. Esto se conoce como el principio de localidad (principle of locality). Por lo tanto, hace sentido remover aquellas páginas que no han sido utilizadas recientemente pues se asume que no serán referenciadas en el futuro inmediato. El s.o. debe llevar un temporizador (timer) que indique cuándo fue la última vez que se referenció cada página para poder decidir cuál remover. Este algoritmo no sufre la anomalía de Belady. Conclusión El Administrador de la Memoria (Memory Manager) tiene la tarea de asignar la memoria a cada programa que debe ser ejecutado y reclamarla cuando termina su ejecución. Una vez que los programas han sido cargados a memoria usando un esquema de asignación, otro módulo del s.o. debe asignar el CPU a cada programa de la forma más eficiente posible.