Espacios de direcciones y traducción de direcciones

Aprende cómo un sistema operativo proporciona a cada programa en ejecución su propia memoria privada y protegida. Comienza por el espacio de direcciones que ve un programa y los objetivos de la virtualización de memoria; después, sigue las solicitudes de memoria del montículo desde malloc y free hasta las llamadas al sistema que las sustentan. Traduce direcciones paso a paso mediante registros base y límite y mediante segmentación, y observa cómo los gestores de espacio libre colocan solicitudes de distintos tamaños, desde el primer ajuste hasta la asignación por bloques compañeros, mientras mantienen bajo control la fragmentación interna y externa.

IntermedioUnidad 3 de 9 del curso Curso de Sistemas operativos

Lo que aprenderás

  1. Describe el espacio de direcciones que ve un programa en ejecución, por qué el sistema operativo virtualiza la memoria y los objetivos que debe cumplir todo esquema de virtualización de memoria.
    • Describe un espacio de direcciones y su organización
      Explica qué es un espacio de direcciones, cómo se organizan en él el código, el montículo y la pila, y en qué se diferencian las direcciones virtuales de las físicas.
    • Evalúa la virtualización de memoria según sus objetivos
      Evalúa un esquema de virtualización de memoria según su transparencia, eficiencia y protección, y distingue el mecanismo del hardware de las políticas del sistema operativo.
  2. Distingue la memoria de pila de la de montículo, solicita y libera memoria del montículo con las llamadas estándar, reconoce los errores que pueden provocar y explica de dónde procede esa memoria.
    • Asigna y libera memoria con la API de memoria
      Distingue la memoria automática de la pila de la memoria del montículo, usa correctamente malloc y free a grandes rasgos y reconoce los principales tipos de errores de memoria.
    • Explica cómo el asignador obtiene memoria del sistema operativo
      Distingue la función del sistema operativo de gestionar el espacio de direcciones de un proceso de la función de la biblioteca de gestionar el montículo, y describe las llamadas al sistema que amplían y reducen la memoria.
  3. Explica cómo la reubicación dinámica por hardware convierte cada dirección virtual en una física, qué aportan el hardware y el sistema operativo y cuáles son las limitaciones de este enfoque.
    • Traduce direcciones virtuales con los registros base y límite
      Aplica la reubicación dinámica sumando la base a cada dirección virtual y comprobándola frente al límite, y compárala con la reubicación estática.
    • Reparte el trabajo entre el hardware y el sistema operativo
      Enumera lo que debe proporcionar el hardware y lo que debe hacer el sistema operativo al crear procesos, cambiar de contexto, gestionar excepciones y terminar procesos para que funcionen base y límite.
    • Evalúa el mecanismo de base y límite
      Sopesa la velocidad y la protección de base y límite frente a la memoria que desperdicia, y explica por qué conduce a la segmentación.
  4. Asigna a cada segmento lógico de un espacio de direcciones su propia base y límite, traduce y comprueba direcciones con registros de segmento y evalúa qué exige la segmentación al sistema operativo.
    • Traduce direcciones segmento a segmento
      Coloca el código, el montículo y la pila de forma independiente en la memoria física y traduce una dirección calculando su desplazamiento dentro del segmento.
    • Identifica el segmento al que se refiere una dirección
      Determina el segmento a partir de los bits superiores de una dirección virtual o de cómo se formó la dirección, y calcula el desplazamiento en binario.
    • Gestiona la pila, la protección y la compartición
      Traduce direcciones de pila con un desplazamiento negativo, usa bits de protección por segmento y explica cómo los procesos comparten código de forma segura.
    • Proporciona soporte a la segmentación y evalúala
      Describe qué debe hacer el sistema operativo para permitir la segmentación, compara la segmentación de grano grueso y fino y explica la fragmentación externa que la limita.
  5. Explica cómo un gestor de espacio libre lleva el registro de la memoria libre y atiende solicitudes de distintos tamaños, compara estrategias de colocación y razona sobre la fragmentación interna y externa.
    • Distingue la fragmentación interna de la externa
      Define los dos tipos de fragmentación, identifícalos en ejemplos y explica por qué un asignador del montículo no puede compactar la memoria.
    • Registra el espacio libre con una lista de bloques libres
      Divide y fusiona bloques libres, usa cabeceras para liberar memoria sin indicar el tamaño y construye la lista de bloques libres dentro de la propia memoria libre.
    • Compara estrategias de colocación
      Aplica mejor, peor, primer y siguiente ajuste a una lista de bloques libres y sopesa su velocidad frente a la fragmentación que causan.
    • Usa listas segregadas y asignación por bloques de objetos y por bloques compañeros
      Explica cómo las listas por tamaño, las cachés de objetos y los bloques compañeros de tamaño potencia de dos aceleran la asignación, y calcula el desperdicio y las fusiones en la asignación por bloques compañeros.

Guía de estudio de Traducción de direcciones

5 capítulos

1

Una vista privada de la memoria para cada proceso

Un puntero pertenece al proceso que lo usa. Su número por sí solo no identifica una celda de memoria física. Los espacios de direcciones permiten que varios programas permanezcan en memoria mientras cada uno se ejecuta con su propia vista del código y los datos. El sistema operativo y el procesador deben mantener esa vista, traducir los accesos con rapidez e impedir que un programa dañe a otro. Estos objetivos explican tanto la organización que ve un programa como los mecanismos que permanecen ocultos detrás de ella.

1.1 La memoria que ve un proceso

Un programa en ejecución trabaja con un espacio de direcciones: su propia vista de la memoria, con ubicaciones de bytes numeradas. El sistema operativo coloca la memoria del programa en la máquina y hace que sus direcciones lleguen a los bytes físicos correctos. La organización que ve el programa y la organización en el hardware son cosas distintas.

Por qué varios programas permanecen en memoria

Los primeros sistemas podían mantener un programa junto al sistema operativo. Por ejemplo, el sistema operativo podía ocupar los primeros 64 KB y el programa la memoria restante. La multiprogramación mantenía listo más de un proceso, de modo que la CPU podía trabajar mientras otro proceso esperaba una entrada o salida. El tiempo compartido cambiaba la CPU entre procesos con suficiente frecuencia para atender a usuarios interactivos.

Guardar en disco toda la memoria de un proceso en cada cambio haría que los cambios fueran demasiado lentos. Mantener varios procesos en la memoria física evita esa copia, pero crea un problema de protección. Una dirección generada por un proceso no debe permitirle sobrescribir el sistema operativo ni un proceso vecino.

Los tamaños de memoria aquí siguen la convención binaria usada en estos modelos: 1 KB son 1024 bytes, también expresados como 1 KiB; 1 MB son 1024 KB. Un espacio de direcciones de 16 KB tiene 16 384 ubicaciones de bytes, numeradas de 0 a 16 383. El número 16 384 es el límite final, no una dirección de byte válida.

Código, datos, montículo y pila
RegiónQué contieneCómo se usa
CódigoInstrucciones de máquinaLa CPU busca instrucciones aquí.
Datos estáticosVariables globales y variables locales estáticasEl almacenamiento dura toda la ejecución del programa.
MontículoBloques solicitados durante la ejecuciónEl programa solicita y libera bloques.
PilaEstado de llamadas a funciones y variables locales ordinariasLas llamadas crean marcos; los retornos los liberan.

En una organización didáctica clásica de 16 KB, el código usa las direcciones bajas, desde 0 hasta el límite de 1 KB. El montículo comienza por encima del código y crece hacia arriba. La pila comienza en el límite superior y crece hacia abajo. El espacio libre entre ambos da a las dos regiones margen para crecer. Las organizaciones reales varían; por ejemplo, cada hilo tiene su propia pila. Las funciones de las regiones siguen siendo útiles incluso cuando cambian sus posiciones.

Sigue un puntero hasta la memoria correcta

Una dirección virtual identifica un byte en el espacio de direcciones de un proceso. Una dirección física identifica un byte en el hardware de memoria de la máquina. Cuando el código C imprime printf("%p", (void *) &x), imprime una dirección virtual. El puntero impreso no revela el byte físico que almacena x.

Supón que dos procesos usan ambos la dirección virtual 1000. Cada dirección se interpreta dentro del espacio de direcciones de su proceso, por lo que los accesos pueden llegar a bytes físicos diferentes. Del mismo modo, el código en la dirección virtual 0 no tiene por qué ocupar la dirección física 0. El sistema operativo puede colocarlo en otro lugar y configurar la traducción por hardware para acceder a él.

El procesador traduce las búsquedas de instrucciones, las cargas y los almacenamientos. El sistema operativo elige y gestiona las correspondencias, incluido el cambio de ubicaciones físicas mientras mantiene estables las direcciones virtuales del programa.

Puntos clave

  • Un espacio de direcciones es la vista de la memoria de un proceso, no su ubicación física.
  • El código, los datos estáticos, el montículo y la pila cumplen distintas funciones de almacenamiento.
  • Las direcciones virtuales se interpretan dentro de un proceso; valores iguales pueden acceder a bytes físicos diferentes.
  • Un espacio de direcciones de 16 KB tiene los bytes de 0 a 16 383 según la convención binaria para KB.

1.2 Transparencia, eficiencia y protección

Un sistema de memoria debe hacer más que traducir correctamente un número. Debe permitir que los programas ordinarios se ejecuten sin gestionar la ubicación física, mantener bajo el coste de la traducción y hacer cumplir los límites que permiten compartir la memoria de forma segura. Estos requisitos son la transparencia, la eficiencia y la protección.

Mantén la vista del programa

La transparencia significa que un programa se ejecuta como si tuviera memoria privada. Usa sus propias direcciones para el código y los datos sin tener que seguir qué otros procesos están presentes ni dónde se encuentran sus bytes. El sistema operativo y el hardware mantienen esta vista de forma transparente. Mover un proceso en la memoria física no debería exigir que el proceso reescriba sus punteros.

La ilusión no requiere una copia física distinta de cada byte para cada proceso. Por ejemplo, el código protegido de solo lectura puede compartirse. Lo que importa es que la compartición mantenga el comportamiento y los derechos de acceso que corresponden a cada proceso.

Ten en cuenta ambos tipos de coste

Cada búsqueda de instrucción, carga y almacenamiento necesita traducción. Ejecutar una rutina del sistema operativo para cada acceso haría que la ejecución ordinaria fuera demasiado lenta. El hardware realiza las operaciones frecuentes; el código del sistema operativo se ocupa de la configuración, los cambios y los fallos.

La eficiencia en espacio también importa. Un mecanismo de traducción pequeño y rápido puede aun así desperdiciar una cantidad considerable de memoria. Una sola región de base y límite reserva el espacio sin usar entre el montículo y la pila. La segmentación evita asignar memoria física a ese espacio, pero introduce regiones físicas de tamaño variable y huecos entre ellas. Los metadatos, el espacio reservado sin usar y los huecos afectan a la cantidad de trabajo útil que cabe en la memoria.

ObjetivoPregunta que debes hacerte
Transparencia¿Sigue el programa usando sus propias direcciones sin gestionar su ubicación?
Eficiencia en tiempo¿Cuánto trabajo añade cada acceso a memoria?
Eficiencia en espacio¿Cuánta memoria consumen los metadatos o el espacio inutilizable?
Protección¿Puede el proceso acceder solo a las regiones y operaciones que tiene permitidas?
Detén un acceso no permitido en el límite

Sin protección, un puntero erróneo en un editor de texto podría sobrescribir otro proceso o el núcleo. El daño podría aparecer mucho más tarde en código sin relación aparente. Cuando se hacen cumplir los límites, el hardware rechaza un acceso fuera de la región permitida y genera una excepción. El sistema operativo gestiona la excepción y suele terminar el proceso defectuoso, normalmente comunicando un fallo de segmentación.

La protección aísla los procesos entre sí. No hace que el uso de la memoria en C sea seguro dentro de una región permitida del montículo. Una escritura que sobrepasa un bloque asignado puede alcanzar otro bloque del mismo proceso. Los límites de los procesos y los límites de los bloques del asignador son distintos.

Separa la operación de la decisión

Un mecanismo es la forma de realizar una operación. Sumar el valor de un registro base y comprobar un registro límite son mecanismos. Una política elige entre las acciones posibles: dónde colocar un proceso, qué hueco libre usar o cuándo mover un segmento.

Mantenerlos separados permite al sistema operativo cambiar su estrategia de colocación y conservar la misma traducción por hardware. La virtualización de memoria comienza con esta vista privada y protegida; no se define por el uso del disco como memoria adicional.

Puntos clave

  • La transparencia mantiene la vista del programa cuando cambia su ubicación física.
  • La eficiencia en tiempo importa en cada acceso a memoria; la eficiencia en espacio incluye las regiones sin usar y los metadatos.
  • La protección aísla los procesos, pero no hace cumplir todos los límites de los bloques del montículo.
  • Los mecanismos realizan operaciones; las políticas eligen entre alternativas.
  • El hardware traduce los accesos ordinarios; el sistema operativo gestiona la traducción y atiende los fallos.
2

De las asignaciones en C a las regiones del sistema operativo

Una solicitud de memoria del montículo atraviesa dos niveles de gestión de memoria. La biblioteca C encuentra un bloque para el programa, mientras que el sistema operativo proporciona y protege las regiones de las que se extraen los bloques. Seguir estos niveles explica por qué una variable puntero y el bloque que apunta tienen tiempos de vida distintos, por qué liberar un bloque puede dejar sin cambios el uso de memoria del proceso y por qué una compilación correcta dice poco sobre la validez de los accesos posteriores al montículo.

2.1 Solicita bloques y respeta sus tiempos de vida

Una variable puntero y la memoria a la que apunta son objetos separados. Comprender sus tiempos de vida es el punto de partida para la API de memoria de C. Las variables locales ordinarias suelen usar almacenamiento automático en la pila, los bloques del montículo duran hasta que se liberan y las variables globales y locales static tienen almacenamiento durante toda la ejecución del programa.

Sigue la asignación, no solo el puntero
void f(void) {
    int x;
    int *p = malloc(sizeof(int));
}

En la organización habitual de la pila, x y p pertenecen a esta llamada a f. El entero solicitado pertenece al montículo. El retorno elimina la variable puntero local, pero no libera el bloque del montículo. Si no queda ninguna copia de la dirección, el programa ha perdido el acceso a un bloque asignado vigente: una fuga de memoria.

malloc(size) solicita al menos esa cantidad de bytes y devuelve un puntero, o NULL cuando no puede atender la solicitud. Sus bytes no están inicializados para el programa. Para 10 enteros, usa malloc(10 * sizeof(int)); donde un entero ocupa 4 bytes, eso solicita 40 bytes. Para una cadena, reserva espacio para sus caracteres más un byte para el carácter nulo de terminación: malloc(strlen(s) + 1).

sizeof(a) mide el objeto llamado a. Si a es un puntero, da el tamaño del puntero, no el de la asignación. Un puntero de 8 bytes puede referirse a un bloque de 40 bytes.

Conoce qué hace cada operación de la biblioteca
LlamadaPropósito principal
mallocObtener un bloque cuyos bytes no se ponen a cero.
callocObtener un bloque lleno de bytes de valor cero.
reallocCambiar el tamaño de un bloque y posiblemente moverlo.
freeDevolver un bloque asignado al asignador.

free recibe el puntero devuelto, sin un argumento de tamaño. El asignador conserva metadatos de tamaño, normalmente en una cabecera antes del bloque. Pasa el puntero devuelto para un bloque actualmente asignado; un puntero al interior del bloque no es un sustituto válido. free(NULL) es válido y no hace nada. Estas funciones son rutinas de la biblioteca C, no llamadas al sistema.

Reconoce el error por el tiempo de vida o el límite

Un puntero sin una asignación válida no puede usarse como si ya apuntara a un espacio de almacenamiento. Leer bytes recién asignados antes de inicializarlos es una lectura de memoria sin inicializar. Escribir más allá del final asignado es un desbordamiento de búfer; omitir el byte de terminación de una cadena puede causarlo.

Después de free, los punteros antiguos al bloque quedan colgantes. Acceder mediante uno de ellos es un uso después de la liberación. Liberar el bloque de nuevo es una doble liberación de memoria. Liberar una dirección que el asignador no devolvió para un bloque vigente es una liberación no válida. Perder un bloque por una fuga es distinto: el bloque permanece asignado, pero el programa deja de liberarlo cuando debería.

Comprende qué puede comprobar el hardware

La compilación puede tener éxito pese a todos estos errores. El hardware suele comprobar las regiones y los permisos del proceso, no cada asignación de la biblioteca. Cruzar el límite de un bloque mientras se permanece dentro del montículo permitido del proceso puede tener un comportamiento indefinido sin provocar un fallo inmediato. El programa puede corromper datos, fallar más tarde, leer valores sin sentido o parecer que funciona. Valgrind y AddressSanitizer pueden detectar muchos de estos errores durante la ejecución.

Puntos clave

  • El tiempo de vida de un bloque del montículo es independiente del de la variable puntero.
  • Usa sizeof para el tipo almacenado; sizeof aplicado a un puntero no mide su bloque.
  • malloc, calloc, realloc y free son rutinas de biblioteca.
  • Una asignación para una cadena necesita espacio para su byte nulo de terminación.
  • free(NULL) no hace nada; un puntero al interior de un bloque no es un puntero válido al bloque asignado.
  • Las comprobaciones de regiones del hardware pueden pasar por alto errores de memoria a nivel de bloque dentro del montículo.

2.2 Cómo obtiene memoria el asignador

La biblioteca C y el sistema operativo gestionan la memoria a distintas escalas. El sistema operativo establece regiones en el espacio de direcciones de un proceso y les proporciona memoria física. El asignador divide la memoria disponible del montículo en bloques, registra los bloques libres y los reutiliza entre llamadas.

Mueve el límite del montículo

El límite del montículo es la dirección situada justo después del final del montículo tradicional. brk establece ese límite en una dirección elegida. sbrk(n) lo desplaza un incremento de bytes y, si tiene éxito, devuelve el límite anterior. sbrk(0) indica el límite actual sin moverlo.

Supón que el límite es 40 960 y que el asignador llama correctamente a sbrk(8192). El valor devuelto es 40 960. El nuevo límite es:

40 960+8192=49 152

Los bytes añadidos ocupan las direcciones virtuales de 40 960 a 49 151. El nuevo límite, 49 152, está justo después de la región añadida. Confundir el valor devuelto con el nuevo límite desplaza todos los cálculos posteriores de colocación.

Las aplicaciones usan la biblioteca de asignación en lugar de mover el límite directamente. La biblioteca lleva el registro de las partes de su región que le pertenecen. Los cambios independientes en ese límite pueden invalidar sus registros.

Obtén un mapeo separado

mmap puede crear una región anónima: memoria no asociada a un archivo, inicialmente llena de bytes de valor cero. munmap elimina un mapeo. Un asignador puede usar mapeos separados para asignaciones grandes y devolver esos mapeos al sistema operativo cuando se liberan.

En glibc, el umbral inicial predeterminado para esta vía es de 128 KB, o 131 072 bytes, y puede aumentar. Una asignación suficientemente grande suele mapearse por separado si no puede atenderse con el espacio libre existente. Esta es una política de la biblioteca, no un límite universal del lenguaje C.

Libera a nivel de biblioteca o de sistema operativo
SucesoQué cambia
Liberar un bloque pequeño reutilizableEl asignador puede atender otra solicitud con él.
Eliminar un mapeo separadoLa región mapeada deja de pertenecer al proceso.
Terminar el procesoEl sistema operativo recupera la memoria del proceso.

Una llamada a free suele devolver un bloque pequeño a la reserva de la biblioteca. Por ello, el proceso puede mostrar después la misma ocupación de memoria. La memoria está disponible para reutilizarse sin otra solicitud al sistema operativo.

La terminación del proceso recupera incluso las asignaciones que el programa perdió por fugas. Sin embargo, durante la vida de un servidor de larga duración, las fugas repetidas siguen consumiendo su memoria disponible. Recuperar la memoria al terminar no evita esa presión mientras se ejecuta.

Relaciona el crecimiento del montículo con la traducción

En el modelo de segmentación, el montículo es un segmento físico contiguo. Ampliarlo requiere bytes físicos libres justo encima de él. Si esos bytes están ocupados, el sistema operativo puede mover el segmento a un hueco mayor y actualizar su estado de traducción. Si no hay una región adecuada disponible, la ampliación falla. Si el asignador no puede obtener suficiente espacio, malloc devuelve NULL.

Puntos clave

  • El sistema operativo proporciona regiones; la biblioteca las divide en bloques.
  • Una llamada a sbrk que tiene éxito devuelve el límite anterior, no el nuevo.
  • mmap anónimo obtiene una región separada llena de ceros; munmap la elimina.
  • Liberar un bloque suele permitir su reutilización sin reducir la memoria del proceso asignada por el sistema operativo.
  • Un montículo segmentado necesita espacio físico contiguo para crecer.
3

Traducción mediante base y límite

Base y límite convierte una dirección relativa a un proceso en una dirección física mediante una comparación y una suma. Su sencillez facilita ver el reparto del trabajo: el hardware comprueba cada acceso, mientras que el sistema operativo elige una ranura, restaura el estado de traducción al cambiar de proceso y gestiona los fallos. Seguir un proceso a través de estos eventos también revela el coste principal: incluso las direcciones sin usar entre el montículo y la pila ocupan parte de su ranura física.

3.1 Comprobación y traducción de una dirección

La reubicación dinámica traduce direcciones mientras se ejecuta un programa. En el modelo de base y límite, un proceso ocupa una región física contigua. Comienza con espacios de direcciones del mismo tamaño que caben en la memoria física; un par de registros describe entonces la región del proceso que se ejecuta en ese momento.

Comprueba primero la dirección virtual

El registro base contiene la dirección física del primer byte de la región. El registro límite contiene el tamaño de la región en bytes. Para una dirección virtual no negativa, la regla es:

0≤direccioˊn virtual<lıˊmite

Si se supera la comprobación:

direccioˊn fıˊsica=base+direccioˊn virtual

De lo contrario, el hardware genera una excepción. Un tamaño es una cantidad, por lo que la dirección igual al límite ya está fuera de la región. Las direcciones virtuales negativas también son inválidas.

Recorre los límites de bytes

Considera un espacio de direcciones de 8 KB con base 20 480 y límite 8192. Sus bytes virtuales van de 0 a 8191. La dirección virtual 1000 supera la comprobación y accede al byte físico 21 480. El último byte virtual permitido, 8191, accede a 28 671. La dirección 9000 falla porque es al menos 8192; el hardware debe rechazarla antes de realizar el acceso físico.

Las búsquedas de instrucciones usan la misma traducción que los datos. Si una instrucción en la dirección virtual 128 carga desde la dirección virtual 3000, la búsqueda accede a la dirección física 20 608 y la carga accede a 23 480. Son dos accesos a memoria con dos direcciones traducidas, no una única traducción compartida para toda la instrucción.

Distingue las convenciones del límite
El registro límite contieneQué se compara
Tamaño de la regiónLa dirección virtual debe ser menor que el tamaño.
Límite físico finalLa dirección traducida debe ser menor que ese límite.

La misma región de 8 KB tiene el límite físico final 28 672. Ambas convenciones permiten exactamente los bytes de 20 480 a 28 671. Comparar la dirección física 21 480 con el tamaño 8192 mezcla las dos convenciones y rechaza incorrectamente un acceso permitido.

Mueve la memoria sin cambiar los punteros

La MMU, o unidad de gestión de memoria, realiza las comprobaciones y la suma. El sistema operativo puede pausar un proceso, copiar su región a otro lugar y cambiar la base. El proceso sigue usando las mismas direcciones virtuales, por eso la reubicación es dinámica.

En la reubicación estática, en cambio, un cargador reescribe las direcciones incorporadas al cargar el código. Reescribir una referencia de 1000 a 21 480 registra una ubicación física en el programa. Moverlo más tarde requiere nuevas reescrituras, y la reescritura por sí sola no impide que un programa construya una dirección fuera de su región.

Suma la base solo a una dirección virtual. Sumarla a una dirección física ya traducida desplaza la ubicación por segunda vez y destruye la correspondencia.

Puntos clave

  • Cuando el límite es un tamaño, comprueba la dirección virtual antes de sumar la base.
  • El intervalo permitido excluye la dirección igual al límite.
  • Tanto las búsquedas de instrucciones como los accesos a datos se traducen.
  • Un límite físico final y un límite expresado como tamaño en bytes usan comparaciones distintas.
  • La reubicación dinámica cambia la ubicación sin reescribir los punteros virtuales.

3.2 Instalación y cambio del estado de traducción

El hardware mantiene los registros de traducción del proceso que se ejecuta en una CPU. El sistema operativo conserva el estado guardado de los procesos que esperan. La protección depende de que solo el código privilegiado del sistema operativo tenga capacidad para cambiar ese estado.

Proporciona las operaciones de hardware

La CPU necesita los modos usuario y núcleo, un par de base y límite en su MMU y circuitos para la comprobación y la suma. También necesita operaciones privilegiadas para cambiar el par e instalar manejadores de excepciones. Las direcciones no permitidas y los intentos de ejecutar instrucciones privilegiadas en modo usuario deben generar excepciones.

Si un programa de usuario pudiera cambiar su base, podría redirigir sus direcciones al núcleo o a otro proceso. Las comprobaciones de límite protegerían entonces la región equivocada. Restringir las actualizaciones forma parte, por tanto, del mecanismo de protección, no es solo una comodidad administrativa.

Crea y ejecuta un proceso

Durante el arranque, el sistema operativo instala sus manejadores de trampas y excepciones, inicia el temporizador de interrupciones y prepara sus registros de memoria libre. Cuando comienza un proceso, el sistema operativo encuentra una ranura física para su espacio de direcciones. Con ranuras de igual tamaño, una lista de bloques libres puede simplemente registrar cuáles están sin usar.

El sistema operativo marca la ranura elegida como ocupada, registra la base y el límite del proceso, carga los registros y entra en modo usuario. El proceso se ejecuta entonces directamente en la CPU. El hardware traduce los accesos ordinarios sin llamar al sistema operativo por cada byte.

Restaura el par correcto en un cambio de contexto

Una interrupción del temporizador transfiere el control al sistema operativo. Este guarda los registros del proceso anterior, incluidos la base y el límite, en su bloque de control de proceso y después restaura los valores del siguiente proceso antes de volver al modo usuario.

Supón que la base de A es 20 480 y la de B es 40 960, ambas con límite 8192. La dirección virtual 1000 de A accede a 21 480. Después de cambiar a B, el mismo número virtual accede a 41 960. Restaurar los registros de la CPU sin restaurar el estado de traducción haría que B accediera a la región de A usando los punteros de B.

La CPU tiene el par activo; cada proceso tiene su propio par guardado. No imagines un único par permanente para toda la máquina ni supongas que los pares de todos los procesos están activos simultáneamente en una CPU.

Mueve, gestiona fallos y termina

Para mover A a la dirección física 49 152, el sistema operativo retira A de la ejecución, copia su región de 8 KB y actualiza la base guardada de A. Una vez que A se reanuda con esa base instalada, la dirección virtual 1000 accede a 50 152. Sus valores de puntero virtual no necesitan cambios.

Ante un acceso no válido, el hardware genera una excepción y transfiere la ejecución al modo núcleo en el manejador registrado. El sistema operativo suele terminar el proceso que causó el acceso. Al terminar, devuelve la ranura a la lista de bloques libres y libera los registros del proceso.

Puntos clave

  • Solo el código privilegiado puede cambiar los registros de traducción.
  • La CPU mantiene el estado activo; los bloques de control de proceso mantienen el estado guardado.
  • Un cambio de contexto debe restaurar la base y el límite junto con los demás registros.
  • La reubicación requiere pausar, copiar y actualizar la base guardada.
  • El hardware genera excepciones de acceso; el sistema operativo las gestiona.
  • La terminación devuelve la ranura física a la lista de bloques libres.

3.3 Por qué una ranura sencilla desperdicia memoria

Base y límite cumple dos objetivos con poco coste: la traducción es transparente y cada dirección se comprueba frente a la región asignada. Su principal debilidad es la relación entre esa región y los bytes que el proceso usa realmente.

Reserva toda la extensión

El hardware solo necesita una suma y una comparación en la ruta frecuente. Un asignador de ranuras de tamaño fijo también puede elegir rápidamente una ranura libre. Ninguna de estas ventajas significa que la ranura esté llena de datos útiles.

En la organización clásica, el código y el montículo están cerca de un extremo y la pila cerca del otro. Un par de base y límite traduce todo el intervalo. El espacio sin usar entre el montículo y la pila ocupa memoria física igual que las partes útiles.

Para un espacio de direcciones de 16 KB que usa 1 KB de código, 2 KB de montículo y 1 KB de pila:

usado=1+2+1=4 KB sin usar=16−4=12 KB fraccioˊn sin usar=1216=75%

El desperdicio es fragmentación interna: bytes sin usar dentro de una región ya asignada a un proceso. No se debe a que el asignador del montículo elija mal un bloque. Incluso un montículo de 2 KB perfectamente aprovechado deja reservado el gran espacio intermedio.

Distingue tres cuestiones de tamaño

La extensión del espacio de direcciones, los bytes usados actualmente y la memoria física disponible son cantidades distintas. Un espacio de 32 bits direccionado por bytes abarca 232 bytes, o 4 GB. Reservarlo como un solo bloque físico requiere los 4 GB completos aunque el proceso solo use actualmente unos pocos megabytes.

RestricciónConsecuencia
Una región contiguaLos huecos libres separados no pueden contener una única región de proceso.
Ranuras de igual tamañoLos procesos pequeños desperdician espacio; los más grandes pueden no caber.
Un espacio de direcciones dispersoLos huecos virtuales sin usar siguen consumiendo memoria física reservada.

Hacer que las ranuras tengan tamaños variables elimina la restricción de igual tamaño, pero no elimina la necesidad de un hueco contiguo. También crea un problema de colocación: el sistema operativo debe elegir entre huecos libres de distintos tamaños. Reducir una ranura no puede mantener tanto las direcciones bajas del código como una dirección alta y distante de la pila si toda la extensión debe seguir siendo válida en el mismo mapeo sencillo.

Reubica las regiones por separado

El código, el montículo y la pila no tienen que ser vecinos en la memoria física para mantener la vista del programa. Dar a cada uno su propia base y límite permite al sistema operativo asignar solo sus extensiones usadas y dejar el espacio virtual sin memoria física asignada. Esto es la segmentación, la generalización de un par de reubicación a varias regiones lógicas.

Para la organización de 16 KB anterior, las tres regiones usadas solo necesitan 4 KB en total antes de su propia sobrecarga de gestión. El ahorro de espacio procede de cambiar lo que se reubica como una unidad, no de hacer más rápida la suma del registro base.

Puntos clave

  • Toda la extensión virtual ocupa una ranura física contigua.
  • El espacio sin usar dentro de esa ranura es fragmentación interna.
  • Las ranuras de igual tamaño limitan a los procesos grandes y desperdician espacio para los pequeños.
  • La segmentación ahorra espacio al reubicar de forma independiente las regiones usadas.
4

Traducción con segmentos separados

Un solo par de traducción reserva los espacios vacíos dentro de un espacio de direcciones. La segmentación da al código, al montículo y a la pila ubicaciones físicas independientes, de modo que solo sus extensiones actuales necesitan memoria física. Traducir una dirección incluye ahora encontrar el segmento y su desplazamiento, con un cambio de signo adicional para la pila que crece hacia abajo. La flexibilidad resultante permite la protección y la compartición de código, a la vez que exige al sistema operativo encontrar huecos contiguos para regiones de distintos tamaños.

4.1 Una traducción propia para cada región

Un segmento es una región contigua de un espacio de direcciones con un propósito. En el modelo clásico, el código, el montículo y la pila reciben cada uno un par de base y tamaño. Sus regiones físicas pueden colocarse de forma independiente aunque el proceso conserve su organización virtual habitual.

Asigna memoria física solo a las extensiones usadas

Usa un espacio de direcciones de 16 KB con las siguientes ubicaciones. Los tamaños usan KB binarios, o KiB.

SegmentoExtensión virtualBase física o límite superiorTamaño
CódigoDe 0 a 2047Base 40 9602048 bytes
MontículoDe 4096 a 7167Base 26 6243072 bytes
PilaDe 14 336 a 16 383Límite superior 53 2482048 bytes

El código y el montículo crecen hacia direcciones mayores; la traducción de la pila usa su límite superior y un desplazamiento negativo. Las tres regiones físicas usan solo 7 KB en total. Los huecos virtuales entre ellas no necesitan almacenamiento físico. Cada segmento sigue siendo contiguo; lo que ya no requiere adyacencia es la relación entre segmentos.

Traduce un segmento que crece hacia arriba

Primero identifica el segmento. Después calcula el desplazamiento desde su comienzo virtual. Comprueba que el desplazamiento no sea negativo y que sea menor que su tamaño actual; luego súmalo a la base física:

desplazamiento=direccioˊn virtual−inicio virtual del segmento direccioˊn fıˊsica=base del segmento+desplazamiento

Para la dirección virtual 500, el desplazamiento dentro del código es 500. Es menor que 2048, por lo que el acceso llega a la dirección física 41 460.

Para la dirección virtual 5000, el desplazamiento dentro del montículo es:

5000−4096=904

La comprobación del tamaño se supera porque 904 es menor que 3072. El resultado es:

26 624+904=27 528

Sumar la dirección virtual completa a la base del montículo produciría 31 624. Eso incorpora por error la posición inicial virtual del montículo a un cálculo que solo necesita la distancia dentro del segmento.

Comprueba el segmento, no solo la extensión del espacio de direcciones

La dirección virtual 7500 cabe en 14 bits, pero eso no significa que esté permitida. Su desplazamiento dentro del montículo es 3404, fuera de la extensión actual de 3072 bytes. El hardware genera una excepción. Una dirección puede estar, por tanto, dentro de la extensión total del espacio de direcciones y aun así fuera de todas las regiones válidas.

El término fallo de segmentación se originó con los accesos segmentados no válidos y sigue usándose para accesos no permitidos en sistemas con otros esquemas de traducción. El nombre del error por sí solo no identifica el mecanismo de traducción de la máquina.

Puntos clave

  • Cada segmento tiene su propia base y tamaño.
  • El desplazamiento de un segmento que crece hacia arriba se mide desde el comienzo virtual de ese segmento.
  • Suma a la base física solo el desplazamiento comprobado.
  • Una dirección dentro de la extensión virtual total puede aun así provocar un fallo.
  • Los huecos virtuales sin usar entre segmentos no requieren memoria física.

4.2 Selección del segmento y extracción de su desplazamiento

Antes de que el hardware pueda usar la base y el tamaño de un segmento, debe decidir a qué segmento se refiere un acceso. Un diseño explícito sitúa esa elección en bits de la dirección. Un diseño implícito la deduce de la forma en que la CPU creó la dirección.

Divide una dirección de 14 bits

Asigna los dos bits superiores al número de segmento y los doce bits inferiores al desplazamiento. El campo de dos bits tiene cuatro valores posibles. Usa 00 para código, 01 para montículo y 11 para pila; deja 10 sin usar.

El campo de desplazamiento puede representar 4096 valores distintos, de 0 a 4095. Por tanto, la ventana virtual máxima de cada segmento es de 4 KB, incluso cuando la extensión válida actual del segmento es menor. La capacidad máxima y el tamaño actual son límites distintos.

Para la dirección virtual 5000, la representación de 14 bits es:

01 0011 1000 1000

El 01 inicial selecciona el montículo. El 0011 1000 1000 restante es 904 en decimal. Con un tamaño de montículo de 3072 y una base física de 26 624, el desplazamiento supera la comprobación de tamaño y llega a la dirección física 27 528.

Usa una máscara y un desplazamiento de bits

La misma división puede expresarse como código:

segment = (va & 0x3000) >> 12;
offset = va & 0x0FFF;

La máscara 0x3000 conserva los dos bits selectores; desplazarlos doce posiciones los mueve a las posiciones inferiores para obtener el número de segmento. La máscara 0x0FFF pone a cero esos bits selectores y conserva el desplazamiento. Para va = 0x1388, los resultados son el segmento 1 y el desplazamiento 0x388, o 904.

No sumes 0x1388 directamente a la base del montículo. Ese valor incluye tanto el selector de segmento como el desplazamiento. El selector elige los registros; solo el desplazamiento interviene en la traducción dentro del segmento. La dirección física resultante no necesita conservar el patrón de bits del selector.

Reconoce el coste de la división

Un selector de dos bits crea cuatro ventanas. Dejar 10 sin usar hace que una cuarta parte de la extensión virtual de 16 KB no esté disponible. Ningún segmento puede crecer más allá de su ventana de 4 KB solo porque quede libre más memoria física. Otros diseños pueden usar una división distinta; combinar el código y el montículo en un segmento permite que un solo bit selector lo distinga de la pila.

Deja que el tipo de acceso elija

En un diseño implícito, las búsquedas de instrucciones usan el segmento de código porque su dirección procede del contador de programa. Las referencias basadas en el puntero de pila o en el puntero de marco usan el segmento de pila. Los demás accesos usan el segmento de montículo en este modelo simplificado.

Método de selecciónDe dónde procede la elección
ExplícitoUn campo de segmento dentro de la dirección virtual
ImplícitoEl registro o tipo de acceso que formó la dirección

Puntos clave

  • Los bits selectores eligen el estado de traducción; los bits de desplazamiento localizan un byte dentro de la ventana.
  • Doce bits de desplazamiento permiten una ventana máxima de segmento de 4096 bytes.
  • La aplicación de una máscara y el desplazamiento de bits separan los campos sin incorporar los bits selectores a la suma de la base.
  • La selección implícita usa el origen de una dirección, como el contador de programa o el puntero de pila.

4.3 Traducción de la pila y aplicación de permisos

La pila crece hacia direcciones menores. Su traducción necesita un bit de dirección de crecimiento además de una base y un tamaño. En este modelo, 1 indica crecimiento hacia arriba y 0 crecimiento hacia abajo. Los permisos de acceso añaden otra comprobación independiente: un byte puede estar dentro de los límites y aun así no permitir la operación solicitada.

Trata la base de la pila como un límite superior

En un segmento que crece hacia arriba, la base identifica su primer byte físico. En un segmento que crece hacia abajo, la base identifica el límite situado justo después de su byte físico de dirección más alta. En la organización del ejemplo, una base de pila de 53 248 y un tamaño de 2048 abarcan los bytes físicos de 51 200 a 53 247.

Para la ventana de pila de 4 KB seleccionada por 11, convierte el campo de desplazamiento de doce bits en un desplazamiento negativo:

desplazamiento negativo=campo de desplazamiento−4096

El campo va de 0 a 4095, por lo que este desplazamiento siempre es negativo. Es válido cuando su magnitud no supera el tamaño actual de la pila. Después suma el desplazamiento con signo a la base.

Resuelve un acceso permitido a la pila

La dirección virtual 15 500 selecciona la pila. Su ventana comienza en la dirección virtual 12 288, por lo que su campo de desplazamiento es 3212. Convierte el campo:

3212−4096=−884

La profundidad 884 está dentro del tamaño 2048. La traducción da:

53 248−884=52 364

Sumar el valor positivo 3212 a la base apuntaría por encima de la pila. El campo todavía no es el desplazamiento necesario para un segmento que crece hacia abajo.

La dirección virtual 13 000 da, en cambio, el campo 712 y el desplazamiento −3384. Su profundidad supera 2048, por lo que el hardware genera un fallo. Si el sistema operativo amplía la pila correctamente, el aumento de su tamaño puede hacer que más direcciones bajas sean válidas.

Incluye el extremo inferior

Un desplazamiento de −2048 llega al byte de dirección más baja de la pila, 51 200, y está permitido. Un desplazamiento de −2049 queda fuera. La comprobación para crecimiento hacia abajo incluye, por tanto, la magnitud igual al tamaño. Esto coincide con el número de bytes de la regla para crecimiento hacia arriba, aunque esa regla excluye un desplazamiento igual al tamaño: la base para crecimiento hacia arriba es un byte, mientras que la base para crecimiento hacia abajo es un límite final.

Comprueba la operación solicitada

Los bits de protección registran los permisos de lectura, escritura y ejecución. El código suele ser de lectura y ejecución; el montículo y la pila suelen ser de lectura y escritura. Una escritura en código de lectura y ejecución provoca un fallo incluso cuando su desplazamiento es válido. Ejecutar datos también provoca un fallo cuando no hay permiso de ejecución.

El código de solo lectura puede compartirse. El sistema operativo puede hacer que los segmentos de código de dos procesos apunten a la misma región física y denegar la escritura en ambos. Los bytes de instrucciones ocupan una sola copia física, mientras cada proceso conserva un montículo y una pila separados.

Puntos clave

  • La base de un segmento que crece hacia abajo marca su límite superior, no un byte almacenado.
  • Resta el tamaño máximo de la ventana al campo de desplazamiento para obtener el desplazamiento negativo.
  • El byte de dirección más baja de la pila está permitido cuando la magnitud del desplazamiento es igual al tamaño actual.
  • Tanto los límites como la operación solicitada deben superar las comprobaciones del hardware.
  • Compartir código de solo lectura ahorra memoria física mientras las regiones privadas de escritura permanecen separadas.

4.4 Gestión de segmentos físicos de tamaño variable

La segmentación sustituye una región grande por varias más pequeñas. Esto evita asignar memoria física a los huecos virtuales vacíos, pero ahora el sistema operativo debe colocar y ampliar regiones de distintos tamaños mientras conserva el estado de traducción de cada proceso.

Guarda todas las partes del mapeo

En un cambio de contexto, la base y el tamaño ya no bastan. El sistema operativo guarda y restaura la base, el tamaño, la dirección de crecimiento y los permisos de cada segmento. Restaurar una pila con la dirección equivocada o código con permisos incorrectos cambiaría el significado de direcciones por lo demás idénticas.

Cuando un asignador necesita más espacio de montículo, el sistema operativo debe ampliar el segmento físico del montículo. Los bytes libres situados justo encima permiten el crecimiento directo. De lo contrario, el sistema operativo puede moverlo a un hueco mayor adecuado y actualizar su base. Si no puede obtener una región adecuada, la ampliación falla.

Elige la granularidad
EsquemaOrganizaciónConsecuencia para la gestión
Segmentación de grano gruesoUnas pocas regiones, como código, montículo y pilaUn pequeño conjunto de registros de segmento describe el proceso.
Segmentación de grano finoMuchas regiones, quizá una por estructura de datosUna tabla de segmentos en memoria permite más opciones de compartición y protección.

Multics usaba segmentación de grano fino. Más segmentos permiten unidades de control más pequeñas, pero requieren más metadatos de traducción y gestión.

Encuentra un hueco suficientemente grande

Los segmentos físicos de tamaño variable dejan huecos libres de distintos tamaños cuando los procesos comienzan, crecen y terminan. La fragmentación externa ocurre cuando hay suficientes bytes libres en total, pero ningún hueco por sí solo puede contener el segmento solicitado.

Supón que los huecos libres son de 8 KB, 6 KB y 10 KB. Su total es 24 KB. Un segmento de montículo de 12 KB sigue sin caber: el hueco disponible más grande es de solo 10 KB. Unir los huecos sobre el papel no hace que sus direcciones físicas sean adyacentes.

La compactación puede corregir esta organización. El sistema operativo pausa los procesos, copia los segmentos uno junto a otro y actualiza sus bases. Las direcciones virtuales siguen funcionando porque la traducción oculta los movimientos físicos. El resultado es una región libre grande y contigua, pero la copia es costosa y las nuevas asignaciones pueden volver a fragmentar la memoria.

Las políticas de colocación, como el primer ajuste y el mejor ajuste, intentan limitar los sobrantes inadecuados sin copiar. Ninguna política de colocación de tamaños variables elimina la fragmentación externa para todas las secuencias de solicitudes. Un único segmento grande también puede desperdiciar espacio dentro de su propia extensión cuando solo se usan partes dispersas.

Reconoce el modelo en los sistemas modernos

La paginación divide la memoria en piezas de tamaño fijo y evita exigir que cada región lógica ocupe un solo hueco físico. El modelo de segmentación sigue siendo útil para comprender las regiones, la protección y la compartición. En el modo de 64 bits de x86-64, las bases ordinarias de segmentación de código, datos y pila actúan como cero y sus límites no se comprueban; FS y GS conservan bases útiles para datos por hilo o por CPU. Un mensaje de acceso no permitido llamado fallo de segmentación no significa que el modelo clásico de tres segmentos esté activo.

Puntos clave

  • Los cambios de contexto restauran la dirección de crecimiento y los permisos, además de las bases y los tamaños.
  • La segmentación de grano fino proporciona más regiones independientes mediante una tabla de segmentos.
  • La fragmentación externa depende del tamaño de cada hueco, no solo del total.
  • La compactación mueve segmentos físicos y actualiza las bases, conservando los punteros virtuales.
  • Las políticas de colocación reducen la fragmentación sin garantizar su eliminación.
  • La traducción ordinaria de x86-64 difiere de la segmentación clásica.
5

Gestión de bloques libres y sus costes

Un asignador debe saber qué bytes están libres y elegir un bloque que pueda contener cada solicitud. La división y la fusión cambian la lista de bloques libres; las políticas de colocación determinan qué huecos quedan para solicitudes posteriores. Las cabeceras, la alineación y el redondeo a potencias de dos añaden sus propios costes. Seguir estos cambios permite explicar fallos de asignación, comparar políticas y ver por qué las cachés especializadas y la asignación por bloques compañeros intercambian flexibilidad por velocidad.

5.1 Localización del desperdicio dentro de los bloques o entre ellos

La gestión del espacio libre registra la memoria disponible y elige dónde colocar cada solicitud. Las solicitudes de igual tamaño pueden usar una lista de bloques intercambiables. Los tamaños variables son más difíciles: tanto un asignador del montículo como un sistema operativo que coloca segmentos deben encontrar un bloque contiguo suficientemente grande para la siguiente solicitud.

Localiza la fragmentación externa

Considera una región de 60 bytes con los bytes 0–19 libres, un bloque asignado en 20–39 y los bytes 40–59 libres. Hay cuarenta bytes libres, pero ninguno de los huecos libres puede contener una solicitud de 25 bytes. El bloque vigente del medio impide tratar esos huecos como una sola región.

Esto es fragmentación externa: hay capacidad libre fuera de los bloques asignados, pero su disposición la hace inutilizable para una solicitud contigua concreta. Los bytes libres no han desaparecido. Aún pueden atender solicitudes más pequeñas o resultar útiles cuando se liberan los bloques intermedios.

Localiza la fragmentación interna

Un asignador que redondea las solicitudes a múltiplos de 16 entrega un bloque de 32 bytes para una solicitud de 20 bytes. Los 12 bytes adicionales están dentro de una asignación ya entregada. Ese desperdicio es fragmentación interna.

El espacio sin usar entre el montículo y la pila en una ranura de base y límite es otro ejemplo. La asignación por bloques compañeros introduce el mismo tipo de desperdicio al redondear a potencias de dos. El nivel de gestión es distinto, pero la ubicación del espacio sin usar es la característica que lo define.

DesperdicioDónde se encuentraQué lo hace costoso
Fragmentación internaDentro de una región asignadaLos bytes reservados superan el contenido útil.
Fragmentación externaEn huecos libres separadosNingún hueco individual se ajusta a la extensión solicitada.

Un mismo asignador puede sufrir ambas. Redondear una solicitud puede desperdiciar bytes dentro de su bloque mientras otros bloques libres permanecen separados en otra parte.

Fusiona vecinos libres sin mover datos vigentes

La fusión de bloques libres adyacentes une bloques libres físicamente adyacentes. Si se libera el bloque del medio de la región de 60 bytes, las tres partes pueden unirse en un hueco de 60 bytes. Si el bloque del medio sigue asignado, la fusión no puede atravesarlo. La fusión reduce la fragmentación externa, pero no garantiza un hueco suficientemente grande para cada solicitud.

Añadir más memoria a un montículo puede aliviar la presión, pero no cambia las direcciones de los bloques vigentes. Su colocación aún puede dejar pequeños huecos inutilizables.

Explica por qué el sistema operativo puede compactar segmentos

El sistema operativo puede copiar segmentos físicos y actualizar sus bases. Los programas conservan las direcciones virtuales, por lo que el mapeo puede ocultar esos movimientos. Un asignador general del montículo de C carece de una capa de traducción entre los punteros devueltos y las ubicaciones dentro del montículo. Un programa puede haber copiado un puntero en muchos objetos y el asignador no puede descubrir ni reescribir cada copia.

Mover un bloque vigente del montículo por sí solo dejaría esos punteros apuntando a su ubicación anterior. Por ello, la gestión ordinaria de malloc mantiene los bloques vigentes en las direcciones devueltas hasta que se liberan. Debe gestionar la fragmentación mediante la colocación, la reutilización, la división y la fusión del espacio libre.

Puntos clave

  • El desperdicio interno está dentro de las asignaciones; la fragmentación externa está en huecos libres separados.
  • La capacidad libre total no demuestra que quepa una solicitud contigua.
  • La fusión une bloques libres adyacentes sin mover bloques vigentes.
  • La reubicación de segmentos del sistema operativo puede conservar los punteros mediante traducción; la compactación ordinaria del montículo de C no puede hacerlo.

5.2 Seguimiento de cabeceras, divisiones y fusiones

Una lista de bloques libres registra los bloques libres por dirección y tamaño. La asignación divide un bloque o lo elimina de la lista; la liberación devuelve un bloque y puede fusionarlo con sus vecinos. La convención de tamaño importa: un tamaño registrado puede indicar la carga útil utilizable o el bloque completo con sus metadatos.

Divide y fusiona intervalos sencillos

Ignora primero las cabeceras. En una región de 60 bytes con entradas libres (0, 20) y (40, 20), una solicitud de 8 bytes colocada al comienzo devuelve la dirección 0. Las entradas restantes son (8, 12) y (40, 20).

Partiendo de nuevo de la organización original, libera los bytes asignados del medio, 20–39. Sin fusión, tres entradas de 20 bytes siguen sin poder atender individualmente una solicitud de 30 bytes. Fusionar los intervalos adyacentes produce (0, 60), que sí puede atenderla. El orden por dirección ayuda al asignador a reconocer los vecinos; la adyacencia en la lista por sí sola no basta si sus intervalos físicos no se tocan.

Recupera la cabecera a partir del puntero del usuario

free(ptr) no recibe un tamaño. Un asignador sencillo guarda una cabecera de tamaño justo antes de la carga útil, a veces con un valor de comprobación o número mágico. Restar la longitud de la cabecera permite encontrar los metadatos.

Con una cabecera de 16 bytes, una solicitud de 96 bytes ocupa 112 bytes en total. El programa recibe un puntero situado 16 bytes después del comienzo del bloque. Al liberarlo se devuelve toda la extensión de 112 bytes, incluida la cabecera, para su gestión futura. La alineación puede añadir redondeo; los tamaños de estos ejemplos ya cumplen una alineación de 16 bytes.

Sigue una lista de bloques libres integrada

Supón que un montículo de 4096 bytes comienza en 32 768. Un nodo libre usa 16 bytes y registra los bytes utilizables después del nodo. Inicialmente registra 4080 bytes utilizables.

Tres solicitudes de 96 bytes consumen 112 bytes cada una:

SolicitudDirección de la cabeceraPuntero devuelto
Primera32 76832 784
Segunda32 88032 896
Tercera32 99233 008

El nodo libre restante comienza en 33 104. Su tamaño utilizable es de 3744 bytes. La contabilización es:

336+16+3744=4096

Liberar el puntero 32 896 permite encontrar la cabecera en 32 880. Ese bloque se convierte en un nodo libre con 96 bytes utilizables. No puede unirse al nodo final en 33 104 porque la tercera asignación está entre ambos. Cuando se liberan y fusionan las tres asignaciones, un solo nodo vuelve a describir 4080 bytes utilizables. Al absorber las antiguas cabeceras interiores, sus bytes quedan disponibles dentro de la extensión fusionada.

Mantén los registros dentro de la región gestionada

Los nodos integrados de la lista están en la propia memoria libre, por lo que gestionar la lista no requiere una asignación separada para cada entrada. El nodo contiene un tamaño y un enlace al siguiente bloque libre. Si ningún bloque sirve, el asignador puede solicitar más memoria con sbrk o mmap; si no consigue suficiente memoria, devuelve NULL.

Un desbordamiento puede sobrescribir una cabecera o un nodo vecino. Esto explica por qué el fallo visible puede producirse durante una llamada posterior a malloc o free, después de la escritura que dañó la lista.

Puntos clave

  • Distingue el tamaño utilizable de la extensión total que incluye los metadatos.
  • Una cabecera de 16 bytes hace que una solicitud de 96 bytes consuma 112 bytes.
  • Encuentra la cabecera de una asignación restando su tamaño al puntero devuelto.
  • La división conserva un resto utilizable; la fusión requiere extensiones libres adyacentes.
  • Los nodos integrados almacenan los metadatos de la lista en los propios bloques libres.
  • Un bloque vigente intermedio impide la fusión.
  • Sobrescribir los registros puede causar fallos en llamadas posteriores al asignador.

5.3 Elección de un bloque libre

Una política de colocación elige entre los bloques suficientemente grandes para una solicitud. Las distintas elecciones dejan huecos diferentes para solicitudes futuras. El tiempo de búsqueda importa junto con la fragmentación, y ninguna política gana para todas las cargas de trabajo.

Compara las reglas de búsqueda
PolíticaElecciónPrincipal contrapartida
Mejor ajusteEl bloque más pequeño que sirveUna búsqueda completa en una lista sencilla puede dejar fragmentos diminutos.
Peor ajusteEl bloque más grandeUna búsqueda completa en una lista sencilla puede consumir un hueco grande valioso.
Primer ajusteEl primer bloque adecuado según el orden de la listaSe detiene pronto, pero los sobrantes pequeños se acumulan cerca del comienzo.
Siguiente ajusteEl primer bloque adecuado desde una posición de búsqueda guardadaDistribuye las búsquedas por la lista y vuelve al comienzo cuando es necesario.

Para el mejor y el peor ajuste, una lista sencilla sin ordenar necesita una búsqueda completa. Otras estructuras pueden encontrar tamaños adecuados más rápidamente. Primer ajuste significa primero en el orden elegido para la lista, lo que no tiene por qué significar la dirección más baja, salvo que la lista esté ordenada por dirección.

Sigue la primera solicitud

Considera bloques libres de 30, 12, 50 y 20 bytes en orden de dirección. Ignora las cabeceras y supón que la división puede conservar cada sobrante. Una solicitud de 18 bytes cambia la lista de la siguiente manera:

  • El mejor ajuste usa 20 y deja 30, 12, 50, 2.
  • El peor ajuste usa 50 y deja 30, 12, 32, 20.
  • El primer ajuste usa 30 y deja 12, 12, 50, 20.
  • El siguiente ajuste, si comienza en el cuarto bloque, usa 20 y deja 30, 12, 50, 2.

El siguiente ajuste necesita una posición inicial para determinar su elección. El nombre por sí solo no implica que sea la primera entrada de la lista. Un seguimiento debe conservar ese estado de búsqueda entre solicitudes.

Observa por qué la siguiente solicitud cambia la evaluación

Una solicitud posterior pide 45 bytes. El mejor ajuste y el primer ajuste conservaron el bloque de 50 bytes, por lo que ambos tienen éxito. El bloque restante más grande del peor ajuste es de 32 bytes, por lo que falla pese a tener 94 bytes libres en total:

30+12+32+20=94

Este fallo es fragmentación externa. La decisión anterior dividió el único hueco suficientemente grande. Por otra parte, el mejor ajuste dejó un fragmento de 2 bytes que puede ser demasiado pequeño para solicitudes futuras útiles. Un resto pequeño inmediato no demuestra que una política vaya a usar bien el espacio durante toda la secuencia de solicitudes.

Equilibra la política y la estructura de datos

Recorrer miles de entradas puede ser costoso incluso cuando cada colocación es buena. Los asignadores prácticos agrupan los bloques por tamaño o usan estructuras que facilitan la búsqueda, como árboles equilibrados. Una lista ordenada por dirección también facilita la fusión al hacer que los vecinos físicos sean más fáciles de encontrar.

El mecanismo de asignación (buscar, dividir, actualizar metadatos) puede seguir siendo el mismo mientras cambia la política. Para comparar políticas de forma justa, sigue las mismas solicitudes y liberaciones, mantén fijas las reglas de sobrecarga y ten en cuenta tanto los huecos resultantes como la cantidad de búsqueda.

Puntos clave

  • El mejor ajuste elige el bloque suficiente más pequeño; el peor ajuste elige el más grande.
  • El primer ajuste depende del orden de la lista; el siguiente ajuste también depende de la posición de búsqueda guardada.
  • Una elección que atiende una solicitud puede impedir una solicitud posterior más grande.
  • Ninguna política de colocación es la mejor para todas las cargas de trabajo.
  • Las estructuras de datos afectan al coste de búsqueda independientemente de la regla de selección.

5.4 Reutilización de tamaños, objetos y bloques compañeros

La búsqueda general en una lista de bloques libres es flexible, pero puede ser costosa. Los asignadores especializados hacen que las solicitudes frecuentes sean predecibles al agrupar tamaños, conservar objetos reutilizables o restringir los tamaños de bloque a potencias de dos.

Reutiliza tamaños frecuentes y objetos inicializados

Las listas segregadas mantienen listas de bloques libres separadas para los tamaños frecuentes, con un asignador general para las demás solicitudes. Atender un tamaño habitual puede consistir en tomar un bloque directamente de su lista. Los bloques de igual tamaño no crean fragmentación externa entre sí, pero dividir la capacidad entre listas es una decisión de política: los bloques sobrantes de un tamaño pueden no servir para otro.

Un asignador por bloques de objetos mantiene una caché de objetos para un tipo de objeto del núcleo que se usa repetidamente, como un inodo, un cerrojo o un descriptor de proceso. Un bloque de objetos se divide en objetos de ese tipo. La caché obtiene más bloques cuando los necesita y puede devolver un bloque completamente libre a un asignador general. Jeff Bonwick diseñó este enfoque para Solaris.

La caché conserva los objetos liberados en un estado inicializado, evitando la configuración y destrucción repetidas. Esto ahorra tiempo además del de la búsqueda.

Divide una región de bloques compañeros

Un asignador binario por bloques compañeros comienza con una región de tamaño potencia de dos y redondea cada solicitud a un tamaño de bloque que sea potencia de dos. Divide repetidamente un bloque libre en mitades iguales hasta que una mitad tiene el tamaño justo. Las dos mitades de una división son bloques compañeros.

Para una solicitud de 5 KB en una región de 64 KB, redondea 5 KB a 8 KB. Divide 64 en dos bloques de 32 KB, después el bloque elegido de 32 en dos bloques de 16 KB y luego el bloque elegido de 16 en dos bloques de 8 KB. Devolver el primer bloque de 8 KB deja bloques compañeros libres en los desplazamientos 8 KB, 16 KB y 32 KB, con tamaños de 8 KB, 16 KB y 32 KB respectivamente.

La asignación desperdicia 3 KB dentro de su bloque de 8 KB. Esto es fragmentación interna, aceptada a cambio de una división y fusión regulares.

Encuentra el único compañero válido para la fusión

Usando desplazamientos medidos desde el comienzo de la región gestionada:

desplazamiento del compan˜ero=desplazamiento del bloque⊕taman˜o del bloque

La operación O exclusiva invierte el bit correspondiente al tamaño del bloque. Para un bloque de 8 KB en el desplazamiento 0, su compañero está en el desplazamiento 8192. Para un bloque de 16 KB en el desplazamiento 16 384, su compañero está en 0.

Cuando se libera el primer bloque de 8 KB, se fusiona con su compañero libre de 8 KB. El bloque de 16 KB resultante puede fusionarse con su compañero libre y, después, el bloque de 32 KB resultante puede volver a fusionarse. La fusión se detiene si el compañero necesario del mismo tamaño está en uso. Estar adyacentes y libres no basta cuando dos bloques no son compañeros de la misma división.

Una solicitud de 20 KB recibe 32 KB y desperdicia 12 KB, o el 37,5 % del bloque. Linux combina la asignación por bloques compañeros de memoria física con cachés de objetos de tipo slab. Los asignadores multihilo también usan cachés locales o varias arenas para reducir la espera por un único cerrojo compartido de asignación; glibc, jemalloc y tcmalloc usan variantes de estas ideas.

Puntos clave

  • Las listas segregadas aceleran las solicitudes de tamaños frecuentes.
  • Las cachés de bloques de objetos reutilizan tipos de objetos frecuentes y pueden evitar la inicialización repetida.
  • La asignación por bloques compañeros redondea a potencias de dos y divide en mitades iguales.
  • El compañero se identifica mediante el desplazamiento relativo a la región XOR el tamaño del bloque.
  • En cada nivel solo puede fusionarse un compañero libre del mismo tamaño.
  • El redondeo a potencias de dos intercambia fragmentación interna por una gestión sencilla.

Ejemplos de Traducción de direcciones

5 Lecciones Interactivas

1

Sigue un puntero a través de una vista privada de la memoria

8 pasos
Relaciona la organización del proceso con la traducción, el aislamiento y la ejecución eficiente.
  1. 1
    IntroducciónUna máquina, varias vistas de la memoria

    Varios procesos pueden permanecer en la memoria física mientras la CPU cambia entre ellos. Cada uno necesita una vista estable de sus propias instrucciones y datos, incluso cuando otros procesos comienzan, terminan o se mueven.

    Un espacio de direcciones proporciona esa vista. El puntero que usa un proceso pertenece a ella; el sistema operativo y el hardware determinan el byte físico al que llega el acceso.

  2. 2
    ExplicaciónSitúa el contenido del programa

    El código almacena instrucciones, los datos estáticos almacenan variables globales y locales estáticas, el montículo almacena bloques solicitados y la pila almacena el estado de las llamadas a funciones.

    En la organización clásica, el montículo crece hacia arriba y la pila hacia abajo, en dirección al espacio que hay entre ambos. Con tamaños binarios, 1 KB significa 1024 bytes, también llamado 1 KiB. Un espacio de 16 KB tiene bytes de 0 a 16 383; su límite superior no es en sí mismo un byte del espacio.

  3. 3
    EjemploDa dos significados al mismo número

    El proceso A y el proceso B usan ambos la dirección virtual 1000. La traducción de A puede enviarla a un byte físico mientras que la de B la envía a otro. El número del puntero por sí solo no identifica un almacenamiento compartido.

    Del mismo modo, imprimir &x muestra una dirección virtual. Mover el almacenamiento físico subyacente no tiene por qué cambiar el valor del puntero que ve el programa.

  4. 4
    DesafíoInterpreta dos punteros impresos

    Dos procesos imprimen el mismo valor de puntero. ¿Deben estar leyendo el mismo byte físico? Explica qué determina el destino.

    ---reveal---

    No. Cada puntero impreso se interpreta en el espacio de direcciones de su propio proceso. El mapeo activo determina el destino físico, por lo que números virtuales iguales pueden llegar a bytes distintos. Para llegar al mismo byte físico se necesitarían mapeos que compartieran realmente el almacenamiento.

  5. 5
    ExplicaciónTraduce con rapidez y haz cumplir los límites

    La transparencia conserva la vista privada del programa. La eficiencia en tiempo mantiene bajo el coste de traducción en cada búsqueda, carga y almacenamiento. La eficiencia en espacio limita los metadatos y la capacidad desperdiciada. La protección detiene los accesos no autorizados.

    El hardware gestiona la traducción ordinaria. El sistema operativo configura los mapeos, elige las ubicaciones y toma el control cuando un acceso genera una excepción.

  6. 6
    DesafíoSepara la elección de la operación

    Un gestor de memoria pasa de elegir el primer hueco adecuado a elegir el hueco adecuado más pequeño. El hardware sigue comprobando los límites y sumando una base. ¿Cambió el mecanismo o la política?

    ---reveal---

    Cambió la política de colocación: ahora hace una elección distinta entre los huecos. El mecanismo de traducción no cambió. El mismo hardware puede traducir y proteger una región independientemente del hueco adecuado que haya elegido el sistema operativo.

  7. 7
    DesafíoRelaciona el movimiento con la protección

    Un sistema operativo mueve un proceso pausado a una nueva región física, pero conserva los valores de sus punteros. ¿Por qué requiere esto tanto traducción como control sobre quién puede cambiar el mapeo?

    ---reveal---

    La traducción redirige los punteros virtuales sin cambiar a los bytes copiados. Solo el código privilegiado del sistema operativo puede instalar el nuevo mapeo; de lo contrario, un proceso podría redirigirse hacia otro proceso o hacia el núcleo. Los punteros estables proporcionan transparencia, mientras que los mapeos controlados conservan el aislamiento.

  8. 8
    RepasoInterpreta el puntero en su proceso

    Un espacio de direcciones organiza el código y los datos de un proceso independientemente de su ubicación física. Un puntero virtual adquiere significado mediante el mapeo del proceso en ejecución.

    Evalúa un diseño por la vista que conserva, sus costes de tiempo y espacio y los límites de acceso que hace cumplir. Las políticas eligen las ubicaciones; los mecanismos realizan la traducción y las comprobaciones.

2

Sigue una solicitud de montículo por la biblioteca y el sistema operativo

12 pasos
Sigue los tiempos de vida de los bloques, las llamadas de biblioteca, el crecimiento del límite del montículo y los mapeos separados.

Guarda esta unidad para seguir cada Lección Interactiva paso a paso.

  1. 1
    IntroducciónTen presentes a los dos propietarios
  2. 2
    EjemploSepara un puntero de su asignación
  3. 3
    ExplicaciónSolicita suficientes bytes
  4. 4
    DesafíoPredice qué permanece tras un retorno
  5. 5
    ExplicaciónLibera solo un bloque vigente
  6. 6
    Idea claveUna región permitida puede contener un acceso no válido a un objeto
  7. 7
    ExplicaciónAmplía una región y después divídela
  8. 8
    DesafíoLocaliza los bytes recién añadidos
  9. 9
    ConexiónLibera un bloque o elimina un mapeo
  10. 10
    DesafíoExplica una ocupación estable de memoria
  11. 11
    DesafíoSigue el crecimiento mediante segmentación
  12. 12
    RepasoSigue por separado el tiempo de vida y la propiedad
3

Ejecuta y mueve un proceso con base y límite

13 pasos
Traduce accesos, restaura el mapeo correcto y calcula el desperdicio de espacio reservado.

Guarda esta unidad para seguir cada Lección Interactiva paso a paso.

  1. 1
    IntroducciónDescribe una ranura física
  2. 2
    ExplicaciónAplica la convención de tamaño
  3. 3
    EjemploTraduce la búsqueda y la carga
  4. 4
    DesafíoComprueba el último byte
  5. 5
    ConsejoReconoce la alternativa para el registro límite
  6. 6
    ExplicaciónProtege los registros de traducción
  7. 7
    EjemploCambia la vista de memoria junto con el estado de la CPU
  8. 8
    DesafíoDetecta una restauración omitida
  9. 9
    ConexiónMueve un proceso sin reescribir punteros
  10. 10
    EjemploMide la extensión sin usar
  11. 11
    DesafíoElige la unidad de reubicación
  12. 12
    DesafíoMantén el límite después de mover un proceso
  13. 13
    RepasoDistingue las coordenadas y los costes
4

Traduce código, montículo y una pila que crece hacia abajo

17 pasos
Extrae campos de segmento, comprueba los extremos exactos y relaciona la compartición con la ubicación física.

Guarda esta unidad para seguir cada Lección Interactiva paso a paso.

  1. 1
    IntroducciónDivide el proceso en regiones lógicas
  2. 2
    ExplicaciónEstablece la organización del ejemplo
  3. 3
    EjemploEncuentra el desplazamiento dentro del montículo
  4. 4
    DesafíoComprueba un byte fuera del montículo
  5. 5
    ExplicaciónUsa bits selectores para elegir registros
  6. 6
    EjemploExtrae ambos campos
  7. 7
    DesafíoSepara la capacidad del uso actual
  8. 8
    ConexiónDeja que el acceso elija un segmento
  9. 9
    ExplicaciónMide hacia abajo desde un límite superior
  10. 10
    EjemploCalcula un desplazamiento de pila con signo
  11. 11
    DesafíoIncluye el byte de dirección más baja de la pila
  12. 12
    Idea claveComprueba el permiso después de encontrar una ubicación válida
  13. 13
    ExplicaciónRestaura más que una base
  14. 14
    DesafíoCuenta los huecos por separado
  15. 15
    ConexiónComprende los límites de la compactación
  16. 16
    DesafíoMueve un segmento compartido de forma segura
  17. 17
    RepasoEncuentra la región antes que el byte físico
5

Sigue los bloques libres y elige políticas de asignación

18 pasos
Sigue los metadatos, compara trazas de colocación y divide y fusiona bloques compañeros.

Guarda esta unidad para seguir cada Lección Interactiva paso a paso.

  1. 1
    IntroducciónPregunta si cabe en un solo bloque
  2. 2
    EjemploLocaliza la capacidad sin usar
  3. 3
    DesafíoComprueba qué puede lograr la fusión
  4. 4
    ConexiónExplica por qué los punteros a bloques vigentes impiden compactar el montículo
  5. 5
    ExplicaciónTen en cuenta la cabecera
  6. 6
    EjemploColoca tres bloques
  7. 7
    EjemploComprueba la extensión restante
  8. 8
    DesafíoRecupera una cabecera y una extensión
  9. 9
    ExplicaciónDeja que la política elija el bloque
  10. 10
    EjemploCompara la primera elección
  11. 11
    DesafíoMira la siguiente solicitud
  12. 12
    ConexiónHaz predecibles las solicitudes frecuentes
  13. 13
    EjemploRedondea y divide una región de bloques compañeros
  14. 14
    ExplicaciónEncuentra el bloque compañero correspondiente
  15. 15
    DesafíoSigue los niveles de fusión
  16. 16
    Idea clavePaga la simplicidad dentro del bloque
  17. 17
    DesafíoSepara la colocación de la fusión
  18. 18
    RepasoSigue tanto la organización como la contabilización

Ejercicios de Traducción de direcciones

50 Preguntas de Práctica en 5 sets

Set 1: Espacios de direcciones, comprobaciones y primeras asignaciones10 Preguntas de Práctica

Pregunta 1 de 10

Dos procesos imprimen cada uno un puntero cuyo valor numérico es 2400. ¿Qué indica esto sobre su almacenamiento físico?
  1. Sus bytes deben ocupar la misma dirección física de memoria.
  2. Sus mapeos pueden situar los bytes en direcciones físicas distintas.
  3. Sus bytes deben tener contenidos idénticos en esa dirección virtual.
  4. Sus direcciones virtuales deben cambiar antes de ejecutar los procesos.
Mostrar respuestaOcultar respuesta
Respuesta: B
Cada puntero se interpreta en el espacio de direcciones de su propio proceso, por lo que valores virtuales iguales pueden llegar a bytes físicos diferentes. Los números iguales no demuestran que el almacenamiento sea compartido. Para compartirlo, los mapeos tendrían que identificar la misma región subyacente.

Pregunta 2 de 10

Un sistema operativo cambia cómo selecciona una ranura libre para un proceso mientras conserva el mismo hardware de comprobación de límites. ¿Qué ha cambiado?
  1. Ha cambiado la regla de privilegios del modo usuario.
  2. Ha cambiado la política de colocación.
  3. Ha cambiado la anchura de dirección del proceso.
  4. Ha cambiado el mecanismo de reubicación.
Mostrar respuestaOcultar respuesta
Respuesta: B
La política elige una ranura entre las alternativas disponibles. El mecanismo sigue comprobando el límite y sumando la base seleccionada exactamente como antes. Llamarlo un nuevo mecanismo de reubicación confunde la decisión de colocación con las operaciones que la hacen cumplir.

Pregunta 3 de 10

Un puntero local es la única referencia utilizable a un bloque asignado. Su función retorna sin liberar el bloque ni guardar el puntero. ¿Qué error de memoria se produce?
  1. Una fuga de memoria por una asignación inaccesible.
  2. Un uso después de la liberación causado por el retorno.
  3. Un desbordamiento de búfer hacia el siguiente bloque del montículo.
  4. Una doble liberación del bloque al que apuntaba el puntero.
Mostrar respuestaOcultar respuesta
Respuesta: A
La asignación del montículo sigue vigente después de que desaparezca el puntero local. Sin una referencia guardada, el programa no puede liberar ni reutilizar ese bloque mediante su dirección de asignación. El retorno de una función no libera por sí mismo el almacenamiento del montículo, por lo que no es un uso después de la liberación.

Pregunta 4 de 10

Un programa asigna almacenamiento para 12 enteros de 4 bytes cada uno. Su tipo de puntero ocupa 8 bytes. ¿Cuántos bytes indica sizeof(p) cuando p contiene la dirección de la asignación?
  1. 4 bytes
  2. 48 bytes
  3. 12 bytes
  4. 8 bytes
Mostrar respuestaOcultar respuesta
Respuesta: D
El operando de sizeof(p) es el objeto puntero, cuyo tamaño indicado es de 8 bytes. La asignación contiene 48 bytes, pero sizeof no sigue un puntero para medir un bloque del montículo. Usar aquí el tamaño de la asignación confunde el puntero con aquello a lo que apunta.

Pregunta 5 de 10

Un proceso tiene base 18 000 y un límite de tamaño de 3000. ¿Qué ocurre cuando carga desde la dirección virtual 2750?
  1. Lee el byte físico 2750.
  2. Provoca un fallo porque 20 750 supera 3000.
  3. Lee el byte físico 20 750.
  4. Lee el byte físico 15 250.
Mostrar respuestaOcultar respuesta
Respuesta: C
La dirección virtual 2750 es menor que el límite de 3000 bytes, por lo que el acceso está permitido. Sumar la base 18 000 da la dirección física 20 750. Comparar ese resultado físico con el límite de tamaño en bytes rechazaría incorrectamente una dirección cuyo desplazamiento virtual cabe.

Pregunta 6 de 10

Con base 24 000 y un límite de tamaño de 4500, ¿qué ocurre con un acceso a la dirección virtual 4500?
  1. El hardware amplía la región en un byte.
  2. El hardware accede al byte físico 28 500.
  3. El hardware rechaza el acceso por estar fuera de los límites.
  4. El hardware accede al byte físico 28 499.
Mostrar respuestaOcultar respuesta
Respuesta: C
Una región de 4500 bytes contiene los bytes virtuales de 0 a 4499. La dirección virtual igual al tamaño es el primer byte situado fuera de ella, por lo que el hardware genera una excepción. Sumar la base antes de aceptar la comprobación no convierte ese límite excluido en un byte permitido.

Pregunta 7 de 10

Un montículo que crece hacia arriba comienza en la dirección virtual 2048, tiene tamaño 1536 y base física 30 000. ¿A qué dirección se traduce la dirección virtual 2900?
  1. Al byte físico 31 536.
  2. Al byte físico 30 852.
  3. Al byte físico 27 952.
  4. Al byte físico 32 900.
Mostrar respuestaOcultar respuesta
Respuesta: B
El desplazamiento dentro del montículo es 852, obtenido al restar el comienzo virtual 2048 de la dirección 2900. Es menor que el tamaño 1536, por lo que al sumarlo a la base 30 000 se obtiene 30 852. Sumar la dirección virtual completa incluiría incorrectamente el comienzo virtual en la reubicación.

Pregunta 8 de 10

Una dirección segmentada usa dos bits selectores superiores y diez bits de desplazamiento inferiores. ¿Cuál es el tamaño máximo en bytes de la ventana de un segmento?
  1. 1024 bytes
  2. 1023 bytes
  3. 4096 bytes
  4. 256 bytes
Mostrar respuestaOcultar respuesta
Respuesta: A
Diez bits de desplazamiento representan 1024 posiciones de bytes, numeradas de 0 a 1023. Los dos bits selectores eligen un segmento en lugar de ampliar su intervalo de desplazamiento. Usar los doce bits para obtener 4096 confunde el espacio de direcciones completo con la ventana de un segmento.

Pregunta 9 de 10

Un montículo tiene huecos libres de 22 y 34 bytes separados por un bloque vigente. Se ignoran las cabeceras. ¿Por qué puede fallar una asignación contigua de 40 bytes?
  1. Ninguno de los huecos libres puede contener 40 bytes por sí solo.
  2. Ambos huecos deben descartarse antes de volver a usarlos.
  3. La solicitud supera toda la capacidad libre combinada.
  4. Los 56 bytes libres están dentro de bloques asignados.
Mostrar respuestaOcultar respuesta
Respuesta: A
Los huecos suman 56 bytes, pero el asignador necesita una extensión ininterrumpida de 40 bytes. El hueco mayor es de solo 34 bytes y el bloque vigente impide fusionar a través de él. Esto es fragmentación externa; los bytes libres están fuera de las asignaciones, no son desperdicio interno.

Pregunta 10 de 10

Un montículo de 512 bytes comienza en 16 000. Cada asignación tiene una cabecera de 16 bytes, sin redondeo. El primer ajuste asigna cargas útiles de 48 y después 64 bytes desde el extremo de direcciones bajas. Se libera el primer bloque. ¿Qué puntero se devuelve para una nueva carga útil de 56 bytes?
  1. 16 144
  2. 16 016
  3. 16 080
  4. 16 160
Mostrar respuestaOcultar respuesta
Respuesta: D
Los dos primeros bloques ocupan 64 y 80 bytes, por lo que la extensión libre final comienza en 16 144. El primer bloque liberado tiene solo 64 bytes en total y no puede contener una carga útil de 56 bytes más su cabecera. El nuevo bloque usa la extensión final y devuelve 16 160; 16 144 es la dirección de su cabecera.
Set 2: Cambios de proceso y decisiones de colocación10 Preguntas de Práctica

Guarda esta unidad para ver todas las respuestas y practicar cada set.

Pregunta 1 de 10

¿Qué región del proceso contiene la dirección de retorno de una llamada ordinaria a una función en la organización habitual?
  1. La región de código.
  2. El montículo.
  3. La pila.
  4. La región de datos estáticos.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 2 de 10

El límite del montículo es 57 344. Una llamada satisfactoria a sbrk(4096) amplía el montículo. ¿Cuáles son el valor devuelto y el nuevo límite?
  1. Valor devuelto 61 440; nuevo límite 61 440.
  2. Valor devuelto 57 344; nuevo límite 53 248.
  3. Valor devuelto 57 344; nuevo límite 61 440.
  4. Valor devuelto 4096; nuevo límite 61 440.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 3 de 10

Un servidor libera varios bloques pequeños, pero su ocupación de memoria medida por el sistema operativo no cambia. ¿Cómo puede ser normal?
  1. La biblioteca conserva las regiones para futuras solicitudes de bloques.
  2. Los punteros siguen vigentes porque la ocupación no cambia.
  3. El sistema operativo retrasa la reutilización hasta que termine el proceso.
  4. Cada bloque liberado debe contener aún una asignación activa.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 4 de 10

El proceso R usa la base 12 000 y el proceso S usa la base 28 000, ambos con límite 2000. Después de cambiar a S, un acceso permitido en la dirección virtual 640 llega a 12 640. ¿Qué estado guardado no se restauró correctamente?
  1. El contenido de la pila del proceso saliente.
  2. El registro base del proceso entrante.
  3. La anchura de dirección virtual del proceso entrante.
  4. El tamaño límite del proceso entrante.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 5 de 10

Una ranura de proceso de 32 KB contiene 3 KB de código, 5 KB de montículo y 4 KB de pila. ¿Qué porcentaje de la ranura reservada está sin usar?
  1. 62,5 %
  2. 37,5 %
  3. 75%
  4. 20%
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 6 de 10

Una pila que crece hacia abajo tiene una ventana de selector de 4096 bytes, base física 60 000 y tamaño actual 1500. Su campo de desplazamiento es 3200. ¿Qué ocurre con una lectura?
  1. Provoca un fallo porque 3200 supera 1500.
  2. Llega al byte físico 63 200.
  3. Llega al byte físico 58 500.
  4. Llega al byte físico 59 104.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 7 de 10

Dos procesos comparten un segmento de código de lectura y ejecución en la misma base física. Uno intenta una escritura dentro de sus límites. ¿Qué debería ocurrir?
  1. El código de ambos procesos cambia en ese byte.
  2. Solo cambia la copia privada de código del proceso que escribe.
  3. Una excepción de permisos bloquea la escritura.
  4. La escritura tiene éxito porque su desplazamiento está permitido.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 8 de 10

Los huecos libres en orden de dirección son de 44, 18, 70 y 32 bytes. Se ignoran las cabeceras; cada asignación toma el extremo de dirección más baja. ¿Qué política atiende solicitudes de 30 y después 65 bytes si ninguno de los bloques se libera entre ellas: primer ajuste, mejor ajuste o peor ajuste?
  1. El primer ajuste y el peor ajuste tienen éxito; el mejor ajuste falla.
  2. El mejor ajuste y el peor ajuste tienen éxito; el primer ajuste falla.
  3. Las tres políticas atienden ambas solicitudes correctamente.
  4. El primer ajuste y el mejor ajuste tienen éxito; el peor ajuste falla.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 9 de 10

El siguiente ajuste encuentra huecos de 16, 48, 24 y 40 bytes. Su búsqueda comienza en el cuarto hueco y vuelve al comienzo si es necesario. Se ignoran las cabeceras. ¿Qué hueco atiende una solicitud de 30 bytes?
  1. El tercer hueco, de 24 bytes.
  2. El segundo hueco, de 48 bytes.
  3. El primer hueco, de 16 bytes.
  4. El cuarto hueco, de 40 bytes.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 10 de 10

Un asignador por bloques compañeros comienza con una región libre de 32 KB e ignora las cabeceras. Atiende dos solicitudes de 6 KB desde los desplazamientos disponibles más bajos y después libera la primera. ¿Cuál es el bloque disponible más grande inmediatamente después?
  1. 24 KB
  2. 16 KB
  3. 32 KB
  4. 8 KB
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Set 3: Seguimiento de límites y del estado del asignador10 Preguntas de Práctica

Guarda esta unidad para ver todas las respuestas y practicar cada set.

Pregunta 1 de 10

Un sistema comprueba correctamente cada dirección virtual, pero entra en código del núcleo en cada carga permitida. ¿Qué objetivo de virtualización se debilita más directamente?
  1. La transparencia de la colocación.
  2. La eficiencia en espacio.
  3. El aislamiento de procesos.
  4. La eficiencia en tiempo.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 2 de 10

Se libera un bloque de 16 bytes del montículo. Después se usa un puntero antiguo para escribir dentro del montículo del mismo proceso, que sigue mapeado, y no se produce un fallo inmediato. ¿Qué describe mejor la escritura?
  1. Una doble liberación porque se reutiliza la dirección.
  2. Una escritura válida porque el montículo sigue mapeado.
  3. Un uso después de la liberación con comportamiento indefinido.
  4. Una fuga porque el bloque nunca se liberó.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 3 de 10

En un modelo de segmentación, un montículo ocupa los bytes físicos de 10 000 a 13 999. Sus 1000 bytes físicos siguientes están ocupados. En otros lugares hay huecos libres de 3000 y 4500 bytes. El asignador necesita ampliar este montículo a 5000 bytes. ¿Puede conseguirlo mediante ampliación directa o reubicación?
  1. La reubicación funciona en el hueco mayor de 4500 bytes.
  2. Ninguna de las dos vías tiene una extensión contigua adecuada.
  3. La ampliación directa funciona porque se necesitan 1000 bytes adicionales.
  4. La reubicación funciona porque los huecos suman 7500 bytes.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 4 de 10

Un proceso con límite de tamaño ocupa los bytes físicos de 36 000 a 40 095. Una instrucción en la dirección virtual 3900 intenta cargar desde la dirección virtual 4096. ¿Qué ocurre?
  1. La búsqueda tiene éxito en 39 900; la carga provoca un fallo.
  2. Ambos accesos fallan; cada uno supera el límite de tamaño.
  3. Ambos accesos tienen éxito en la región asignada.
  4. La búsqueda tiene éxito en 39 900; la carga usa 40 096.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 5 de 10

Un sistema operativo copia un proceso pausado desde la base 22 000 a la base 47 000 sin cambiar su límite. ¿A dónde debería llegar su puntero virtual 960 después de reanudarse?
  1. Al byte físico 22 960.
  2. Al byte físico 69 960.
  3. Al byte físico 25 960.
  4. Al byte físico 47 960.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 6 de 10

Una dirección virtual de 14 bits usa dos bits selectores y doce bits de desplazamiento. El selector 01 identifica un montículo que crece hacia arriba con base 52 000 y tamaño 900. ¿Qué ocurre con una lectura en la dirección virtual 0x1380?
  1. Provoca un fallo porque 0x1380 supera el tamaño 900.
  2. Llega al byte físico 52 896.
  3. Llega al byte físico 52 900.
  4. Llega al byte físico 56 992.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 7 de 10

Un sistema operativo tiene huecos libres de 5 KB, 11 KB y 7 KB, separados por segmentos asignados. Debe colocar un segmento de 13 KB sin mover segmentos vigentes. ¿Por qué puede fallar la solicitud?
  1. Cada segmento debe usar una ranura del mismo tamaño fijo.
  2. El hueco existente más grande es de solo 11 KB.
  3. Los huecos libres suman menos de 13 KB.
  4. El segmento debe usar primero el hueco más pequeño.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 8 de 10

Un montículo de 1024 bytes situado en 8000 usa cabeceras de asignación de 16 bytes y nodos libres de 16 bytes. Cada nodo libre registra los bytes utilizables después de sí mismo. Se asignan dos cargas útiles de 80 bytes desde el extremo de direcciones bajas. ¿Cuáles son la dirección y el tamaño utilizable del nodo libre restante?
  1. Dirección 8192; tamaño utilizable 816 bytes.
  2. Dirección 8192; tamaño utilizable 832 bytes.
  3. Dirección 8160; tamaño utilizable 848 bytes.
  4. Dirección 8224; tamaño utilizable 800 bytes.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 9 de 10

Un núcleo asigna repetidamente el mismo tipo de objeto y la inicialización de ese tipo es costosa. ¿Qué diseño permite directamente reutilizar objetos inicializados?
  1. Una caché de bloques de objetos.
  2. Un cursor de siguiente ajuste.
  3. Un registro de límite de tamaño.
  4. Un reubicador estático.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 10 de 10

En una región de bloques compañeros, ¿cuál es el desplazamiento del compañero de un bloque de 8 KB situado en el desplazamiento 24 KB respecto al comienzo de la región?
  1. 8 KB
  2. 0 KB
  3. 16 KB
  4. 32 KB
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Set 4: Explicación de fallos y conservación de mapeos10 Preguntas de Práctica

Guarda esta unidad para ver todas las respuestas y practicar cada set.

Pregunta 1 de 10

Una función contiene un contador local estático y un contador local automático ordinario. ¿El almacenamiento de qué contador permanece entre llamadas sucesivas?
  1. El de ambos contadores locales.
  2. El de ninguno de los contadores locales.
  3. El del contador local estático.
  4. El del contador automático local.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 2 de 10

Una cadena de C contiene 23 caracteres visibles de un byte cada uno. Un programa asigna exactamente 23 bytes y copia los caracteres seguidos de un carácter nulo de terminación. ¿Qué sale mal?
  1. El primer carácter es una lectura de memoria sin inicializar.
  2. El propio puntero necesita 24 bytes de almacenamiento.
  3. El asignador recibe una solicitud de liberación no válida.
  4. El carácter de terminación se escribe fuera del bloque.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 3 de 10

Dos procesos reservan cada uno una ranura de base y límite de 24 KB. Cada uno usa 2 KB de código, 3 KB de montículo y 1 KB de pila. ¿Cuánto almacenamiento físico consumen juntas sus ranuras reservadas?
  1. 12 KB
  2. 48 KB
  3. 24 KB
  4. 36 KB
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 4 de 10

Una reserva física de 48 KB contiene tres procesos. Cada uno tiene una extensión virtual de 16 KB, pero usa actualmente extensiones contiguas de código, montículo y pila que suman 5 KB. Llega un cuarto proceso idéntico. Si se ignoran los metadatos y la fragmentación, ¿pueden admitirlo base y límite para el espacio completo y la segmentación por separado?
  1. Base y límite no puede; la segmentación sí puede.
  2. Ambos esquemas pueden admitir el cuarto proceso.
  3. La segmentación no puede; base y límite sí puede.
  4. Ninguno de los esquemas puede admitir el cuarto proceso.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 5 de 10

Un montículo que crece hacia arriba comienza en la dirección virtual 8192, con tamaño 2000 y base física 40 000. ¿Qué ocurre con una lectura en la dirección virtual 10 192?
  1. Llega al byte físico 50 192.
  2. Llega al byte físico 41 999.
  3. Provoca un fallo en el extremo excluido del segmento.
  4. Llega al byte físico 42 000.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 6 de 10

Un montículo que crece hacia arriba comienza en la dirección virtual 4096 y tiene tamaño 1500. Su base física cambia de 20 000 a 46 000 tras una reubicación. Una traza muestra entonces que la dirección virtual 5300 llega a la física 51 300. ¿Qué corrección se necesita?
  1. Usar la dirección física 47 204 tras restar el comienzo virtual del montículo.
  2. Usar la dirección física 21 204 restaurando la base original.
  3. Mantener la dirección física 51 300 porque la reubicación cambia toda la dirección.
  4. Usar la dirección física 50 096 sustituyendo el desplazamiento por el comienzo.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 7 de 10

Una dirección de 14 bits usa dos bits selectores y doce bits de desplazamiento. El selector 11 identifica una pila que crece hacia abajo con base física 70 000 y tamaño actual 1024. Se permiten las lecturas. ¿Qué ocurre en la dirección virtual 15 360?
  1. Llega a la dirección física 73 072 al sumar el campo positivo.
  2. Llega al byte de dirección más baja de la pila, el físico 68 976.
  3. Provoca un fallo porque la magnitud del desplazamiento iguala el tamaño.
  4. Llega a la dirección física 68 975 como último byte permitido.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 8 de 10

Un asignador redondea cada solicitud de carga útil a un múltiplo de 32 bytes e ignora las cabeceras. ¿Qué tipo y cantidad de desperdicio crea una solicitud de 70 bytes?
  1. 32 bytes de fragmentación externa.
  2. 6 bytes de fragmentación interna.
  3. 26 bytes de fragmentación externa.
  4. 26 bytes de fragmentación interna.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 9 de 10

Un montículo de 100 bytes tiene bloques vigentes en los bytes 20–39 y 60–79; todos los demás bytes están libres. Se libera el primer bloque vigente y se fusionan los bloques libres adyacentes. Si se ignoran los metadatos, ¿puede entonces tener éxito una solicitud de 65 bytes?
  1. No; la extensión libre más grande es de 40 bytes.
  2. Sí; hay 80 bytes libres en total.
  3. Sí; liberar un bloque une todo el montículo.
  4. No; la extensión libre más grande es de 60 bytes.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 10 de 10

Los huecos en orden de dirección son de 26, 58 y 42 bytes. Se ignoran las cabeceras. El primer ajuste y el mejor ajuste asignan cada uno 24 bytes y después 40 bytes, sin liberaciones. ¿Qué política puede atender entonces una solicitud de 55 bytes?
  1. Ninguna puede atender la solicitud de 55 bytes.
  2. El primer ajuste puede; el mejor ajuste no.
  3. El mejor ajuste puede; el primer ajuste no.
  4. Ambas pueden atender la solicitud de 55 bytes.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Set 5: Razonamiento combinado sobre traducción y asignación10 Preguntas de Práctica

Guarda esta unidad para ver todas las respuestas y practicar cada set.

Pregunta 1 de 10

Un diseño proporciona a dos procesos una región física de código de solo lectura y regiones separadas en las que pueden escribir. ¿Qué objetivos de virtualización puede cumplir esto mientras ahorra espacio?
  1. La transparencia requiere código compartido escribible para ambos.
  2. La eficiencia en espacio requiere eliminar todas las comprobaciones de acceso.
  3. Se pueden conservar tanto la transparencia como el aislamiento.
  4. El aislamiento solo se conserva con copias de código separadas.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 2 de 10

Un montículo segmentado ocupa los bytes físicos de 20 000 a 23 999, seguidos de memoria ocupada. Su límite está en la dirección virtual 10 000. El sistema operativo mueve el montículo a una región libre de 6000 bytes en la dirección física 40 000 y concede correctamente sbrk(1500). ¿Qué devuelve sbrk y dónde se encuentra ahora el primer byte existente del montículo?
  1. Devuelve 11 500; primer byte existente en 40 000.
  2. Devuelve 10 000; primer byte existente en 40 000.
  3. Devuelve 41 500; primer byte existente en 40 000.
  4. Devuelve 10 000; primer byte existente en 20 000.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 3 de 10

Un programa en modo usuario intenta establecer su registro base en el comienzo físico del núcleo. ¿Qué debería hacer el procesador?
  1. Tratar la base solicitada como un puntero virtual ordinario.
  2. Instalar la base y confiar en la comprobación de tamaño existente.
  3. Generar una excepción por la operación privilegiada.
  4. Instalar la base solo para la siguiente carga de este programa.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 4 de 10

Una dirección de 14 bits tiene dos bits selectores y doce bits de desplazamiento. El selector 01 identifica un montículo que crece hacia arriba con base 26 000 y tamaño 1200. Después, su tamaño aumenta a 1400. ¿Cómo cambia una lectura en la dirección virtual 0x1500?
  1. Pasa de provocar un fallo a llegar al byte físico 27 280.
  2. Sigue estando permitida en el byte físico 27 280.
  3. Sigue provocando un fallo porque cambia el selector.
  4. Pasa de provocar un fallo a llegar al byte físico 31 376.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 5 de 10

Después de pausar los procesos y compactar sus segmentos físicos, ¿qué datos de mapeo debe corregir el sistema operativo para los segmentos que movió?
  1. Sus bases físicas.
  2. Sus punteros virtuales.
  3. Sus derechos de acceso.
  4. Sus desplazamientos de código.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 6 de 10

La memoria física tiene el segmento vigente A en los bytes de 0 a 3999, un hueco libre en los bytes de 4000 a 5999, el segmento vigente B en los bytes de 6000 a 8999 y un hueco libre en los bytes de 9000 a 11 999. B puede moverse. ¿Dónde puede moverse B para que después quepa un nuevo segmento de 4500 bytes?
  1. Mover B a los bytes de 5000 a 7999.
  2. Mover B a los bytes de 8000 a 10 999.
  3. Mover B a los bytes de 7000 a 9999.
  4. Mover B a los bytes de 4000 a 6999.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 7 de 10

Un montículo de 640 bytes comienza en 24 000. Las asignaciones tienen cabeceras de 16 bytes y no hay redondeo. Se asignan cargas útiles de 64, 96 y 64 bytes consecutivamente desde el extremo de direcciones bajas. Se liberan y fusionan las dos primeras. El primer ajuste atiende después una carga útil de 144 bytes. ¿Qué puntero y qué resto libre total dentro de ese bloque fusionado resultan?
  1. Puntero 24 016; resto de 32 bytes.
  2. Puntero 24 016; resto de 48 bytes.
  3. Puntero 24 096; resto de 32 bytes.
  4. Puntero 24 000; resto de 48 bytes.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 8 de 10

Los huecos en orden de dirección son de 36, 64 y 48 bytes. Se ignoran las cabeceras. Llega una solicitud de 32 bytes y después una de 60 bytes. El siguiente ajuste comienza su primera búsqueda en el segundo hueco y la reanuda en el resto de ese hueco. ¿Qué política puede atender ambas solicitudes: el mejor ajuste o este siguiente ajuste?
  1. Ninguna de las dos políticas puede atender ambas solicitudes.
  2. El mejor ajuste puede; el siguiente ajuste no.
  3. Ambas políticas pueden atender ambas solicitudes.
  4. El siguiente ajuste puede; el mejor ajuste no.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 9 de 10

Un asignador por bloques compañeros ignora la sobrecarga en una región de 32 KB. Asigna 7 KB en el desplazamiento 0, otros 7 KB en el desplazamiento 8 KB y 12 KB en el desplazamiento 16 KB. Se liberan ambas asignaciones de 7 KB. ¿Por qué no puede atender una nueva solicitud de 20 KB?
  1. Las dos asignaciones liberadas aportan solo 14 KB, por lo que no pueden formar un bloque de 16 KB.
  2. El bloque necesario de 32 KB no puede formarse mientras su compañero superior de 16 KB esté vigente.
  3. Al bloque disponible de 16 KB le faltan solo 4 KB para el tamaño de bloque necesario.
  4. Los bloques libres inferiores siguen separados porque la fusión de compañeros necesita una nueva división.
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

Pregunta 10 de 10

Un proceso con base y límite tiene la base física 11 500. ¿Qué dirección física corresponde a su dirección virtual permitida 700?
  1. 10 800
  2. 700
  3. 11 500
  4. 12 200
Mostrar respuestaOcultar respuesta

Guarda esta unidad para ver esta respuesta.

¿Te atascas con una pregunta tuya? Ayuda con Tareas

Términos Clave

73 Términos Clave, cada uno con su definición

A

Aislamiento
El aislamiento es la separación que se impone entre procesos para que un acceso no autorizado no pueda leer ni corromper otro proceso o el núcleo.
El hardware rechaza el acceso de un editor fuera de su región permitida antes de que dañe un proceso vecino.
Almacenamiento estático
El almacenamiento estático es el almacenamiento de las variables globales y las variables locales estáticas que dura toda la ejecución del programa, independientemente de las llamadas individuales.
Un contador local estático conserva su valor entre llamadas en lugar de desaparecer con cada marco de pila.
Arena de asignación
Una arena de asignación es una región gestionada por separado por el asignador y usada junto con otras arenas para reducir la competencia por un único cerrojo compartido de asignación.
Los hilos que usan distintas arenas pueden atender muchas solicitudes sin esperar por el mismo cerrojo del asignador.
Asignador por bloques compañeros
Un asignador por bloques compañeros gestiona bloques de tamaño potencia de dos, los divide en mitades iguales y fusiona un bloque liberado solo con su compañero libre correspondiente.
Una solicitud de 10 KB recibe un bloque de 16 KB, que deja 6 KB sin usar dentro de esa asignación.
Asignador por bloques de objetos
Un asignador por bloques de objetos mantiene cachés de tipos de objetos frecuentes en bloques, lo que permite reutilizarlos con rapidez y reducir el trabajo de inicialización repetido.
Un núcleo puede obtener otro descriptor de proceso de su caché de objetos en lugar de construir uno nuevo.

B

Bits de protección
Los bits de protección especifican las operaciones permitidas en una región, como lectura, escritura o ejecución, que se comprueban por separado de los límites.
Un desplazamiento de código válido sigue provocando un fallo cuando el proceso intenta escribir en almacenamiento de lectura y ejecución.
Bloque asignado vigente
Un bloque asignado vigente es un bloque que sigue perteneciendo al programa y aún no se ha liberado, cuya dirección devuelta debe conservar un asignador ordinario de C.
Un bloque vigente entre huecos libres impide que el asignador fusione esos huecos a través de él.
Bloque compañero
Un bloque compañero es el bloque del mismo tamaño creado al dividir un bloque padre, que se identifica aplicando XOR al desplazamiento de su compañero y al tamaño del bloque.
Dos bloques adyacentes de 8 KB no pueden fusionarse salvo que sean los compañeros de una misma división de 16 KB.
Bloque de control de proceso
Un bloque de control de proceso es un registro del sistema operativo que contiene el estado de ejecución guardado de un proceso, incluidos los valores de traducción cuando el proceso está inactivo.
El sistema operativo restaura la base y el límite guardados del siguiente proceso desde su bloque de control de proceso.
brk
brk establece el límite final del montículo tradicional en una dirección especificada, lo que permite al asignador cambiar el tamaño de esa región.
El asignador gestiona los registros del límite, por lo que el código de las aplicaciones debe solicitar bloques mediante la biblioteca.

C

Cabecera de asignación
Una cabecera de asignación son metadatos almacenados antes de una carga útil devuelta, que suelen registrar el tamaño para que el asignador pueda procesar una llamada posterior a free.
Con una cabecera de dieciséis bytes, un puntero de carga útil de 8016 lleva a los metadatos en 8000.
calloc
calloc es una función de asignación de la biblioteca C que proporciona almacenamiento lleno de bytes de valor cero, a diferencia del almacenamiento sin poner a cero que devuelve malloc.
Un búfer obtenido mediante calloc comienza con bytes de valor cero antes de que el programa escriba datos.
Cambio de contexto
Un cambio de contexto sustituye el estado activo de CPU del proceso en ejecución por el estado guardado de otro proceso, incluidos sus valores de traducción de memoria.
Restaurar los registros generales del siguiente proceso sin su base dejaría activa la vista de memoria equivocada.
Campo de desplazamiento
Un campo de desplazamiento es la parte de una dirección segmentada que localiza un byte dentro de una ventana de selector, antes de cualquier ajuste por crecimiento hacia abajo.
Un campo de doce bits permite 4096 posiciones aunque el segmento seleccionado use actualmente menos bytes.
Carga útil
Una carga útil es la parte de un bloque asignado disponible para el programa, excluidas la cabecera del asignador y sus demás registros.
Una carga útil de 96 bytes con una cabecera de dieciséis bytes ocupa al menos 112 bytes de la región gestionada.
Compactación
La compactación junta regiones físicas vigentes y actualiza sus mapeos para combinar la capacidad libre dispersa en un hueco mayor.
El sistema operativo copia segmentos y cambia sus bases mientras los programas siguen usando las mismas direcciones virtuales.
Compartición de código
La compartición de código permite que los procesos ejecuten una sola copia física de instrucciones inmutables mientras mantienen separado el estado de cada proceso en el que pueden escribir.
Dos procesos pueden usar la misma base de código de solo lectura con bases distintas para el montículo y la pila.
Contención de cerrojos
La contención de cerrojos ocurre cuando hilos concurrentes esperan para acceder al mismo estado protegido del asignador, lo que limita el avance paralelo de las asignaciones.
Las cachés locales y las múltiples arenas reducen el número de asignaciones que necesitan un mismo cerrojo.

D

Desbordamiento de búfer
Un desbordamiento de búfer es una escritura más allá del final asignado de un búfer, que puede corromper datos vecinos o registros del asignador.
Copiar una cadena en un espacio sin un byte para su carácter nulo de terminación puede desbordar el búfer.
Desplazamiento dentro del segmento
Un desplazamiento dentro del segmento localiza un byte respecto al origen virtual de su segmento; en la traducción hacia arriba, el desplazamiento comprobado se suma a la base física.
El byte virtual 5100 en un montículo que comienza en 4096 tiene un desplazamiento de 1004 antes de la reubicación física.
Desplazamiento negativo
Un desplazamiento negativo mide un acceso a un segmento que crece hacia abajo por debajo de su límite superior y se obtiene restando el tamaño completo de la ventana.
Un campo de 3000 en una ventana de pila de 4096 bytes da un desplazamiento de −1096.
Dirección de crecimiento
La dirección de crecimiento de un segmento registra si su región válida se extiende hacia arriba desde un primer byte o hacia abajo desde un límite superior.
La dirección de crecimiento de la pila cambia cómo interpreta el hardware el campo inferior de la dirección antes de sumar la base.
Dirección física
Una dirección física identifica una ubicación en el hardware de memoria a la que se llega tras traducir un acceso a la memoria virtual de un proceso.
La dirección virtual 800 de dos procesos puede traducirse a direcciones físicas distintas en la misma máquina.
Dirección virtual
Una dirección virtual identifica un byte en la vista de memoria de un proceso y se traduce antes de que el procesador acceda a la memoria física.
Un puntero impreso por un programa C muestra una dirección virtual incluso cuando el sistema operativo mueve su almacenamiento físico.
División de bloques
La división de bloques separa un bloque libre en una parte asignada y una parte libre restante, conservando esta última para solicitudes posteriores.
Una solicitud de 24 bytes tomada de un bloque de 80 bytes deja 56 bytes cuando se ignoran las cabeceras.
Doble liberación de memoria
Una doble liberación de memoria es un intento de volver a liberar la misma asignación después de que ya se haya liberado, lo que infringe las reglas de propiedad del asignador.
Llamar a free dos veces mediante punteros copiados a un mismo bloque puede corromper el estado de la biblioteca de asignación.

E

Espacio de direcciones
Un espacio de direcciones es la vista de la memoria disponible para un proceso en ejecución, incluidas las regiones para instrucciones, datos, bloques del montículo y llamadas a funciones.
Dos procesos pueden usar la misma organización del espacio de direcciones mientras sus bytes ocupan regiones físicas distintas.
Espacio de direcciones disperso
Un espacio de direcciones disperso tiene grandes huecos virtuales sin usar entre las regiones utilizadas, lo que hace que asignar físicamente toda su extensión desperdicie memoria.
Separar el montículo y la pila en segmentos independientes evita reservar el espacio vacío entre ambos.

F

Fallo de segmentación
Un fallo de segmentación es un acceso no permitido a memoria que se comunica como error; el nombre persiste incluso cuando la máquina no usa segmentación clásica.
Una infracción de permisos puede producir un fallo de segmentación incluso cuando su desplazamiento está dentro de la región.
Fragmentación externa
La fragmentación externa deja la memoria libre en huecos separados demasiado pequeños para una solicitud contigua, pese a tener suficiente capacidad libre total.
Los huecos de 7 KB y 9 KB no pueden contener un solo segmento de 12 KB, aunque suman 16 KB.
Fragmentación interna
La fragmentación interna es capacidad sin usar dentro de una región asignada, causada por reservar más espacio del que necesita su contenido útil.
Una ranura de proceso de 16 KB que contiene 4 KB de contenido útil desperdicia 12 KB dentro de su asignación.
free
free es una función de la biblioteca C que devuelve un bloque asignado vigente al asignador; pasarle NULL está permitido y no tiene efecto.
El asignador puede reutilizar un bloque liberado incluso si la ocupación de memoria del proceso medida por el sistema operativo sigue siendo la misma.
Fuga de memoria
Una fuga de memoria ocurre cuando el almacenamiento asignado deja de liberarse cuando debería, a menudo porque el programa pierde su último puntero utilizable a él.
Una función que retorna sin conservar ni liberar su único puntero al montículo deja un bloque inaccesible.
Fusión de bloques libres adyacentes
La fusión de bloques libres adyacentes une bloques libres contiguos en un bloque libre mayor sin mover asignaciones vigentes, lo que reduce las entradas separadas de la lista de bloques libres.
Liberar un bloque intermedio puede permitir que dos huecos vecinos se unan en una extensión utilizable para una asignación.

G

Gestión del espacio libre
La gestión del espacio libre lleva el registro de los bloques disponibles y elige dónde colocar las solicitudes, tanto en el montículo de un proceso como en las regiones físicas del sistema operativo.
Un asignador debe encontrar un solo bloque suficiente aunque el total de bytes libres supere la solicitud.

I

Instrucción privilegiada
Una instrucción privilegiada es una operación permitida solo en modo núcleo, lo que impide que los programas de usuario cambien el estado protegido de la máquina.
Un intento de actualizar el registro base desde el modo usuario genera una excepción en lugar de cambiar el mapeo.

L

Lectura de memoria sin inicializar
Una lectura de memoria sin inicializar usa datos almacenados antes de que el programa haya establecido su valor, como cuando lee bytes sin inicializar devueltos por malloc.
Asignar suficiente espacio para un entero no le proporciona un valor inicial significativo.
Límite del montículo
El límite del montículo es la dirección virtual situada justo después del final del montículo tradicional, que se mueve cuando esa región se amplía o reduce.
Si el límite es 30 000, el byte 30 000 está fuera del montículo hasta que el límite se desplace hacia una dirección mayor.
Lista de bloques libres
Una lista de bloques libres registra los bloques disponibles y sus tamaños, con enlaces u otra estructura que permite al asignador encontrar y actualizar las entradas.
Después de dividir un bloque, su parte final sin usar permanece en la lista de bloques libres si puede contener un nodo libre utilizable.
Listas segregadas
Las listas segregadas mantienen reservas separadas para tamaños de bloque seleccionados, de modo que las solicitudes de tamaños frecuentes puedan atenderse sin una búsqueda general.
Una reserva de bloques de 64 bytes atiende rápidamente solicitudes repetidas que pertenecen a esa clase de tamaño.

M

malloc
malloc es una función de la biblioteca C que solicita un bloque de un tamaño en bytes y devuelve su dirección, o NULL si falla, sin poner a cero su contenido.
Una solicitud para seis enteros usa malloc(6 * sizeof(int)) para tener en cuenta el tamaño del elemento.
Manejador de excepciones
Un manejador de excepciones es código del sistema operativo al que se accede después de que el hardware detecte un evento, como una dirección de memoria no válida o una instrucción prohibida.
Una infracción de límites transfiere el control al manejador registrado, que normalmente termina el proceso.
Mapeo anónimo
Un mapeo anónimo es una región de memoria virtual llena de ceros que se crea sin asociar su almacenamiento a un archivo.
Un asignador puede obtener una región grande y separada mediante una solicitud anónima de mmap.
Máscara de bits
Una máscara de bits selecciona posiciones de bits elegidas mediante una operación bit a bit, lo que permite al hardware o al código separar campos de dirección.
Aplicar va & 0x0FFF conserva doce bits inferiores mientras pone a cero los dos bits de segmento de una dirección de catorce bits.
Mecanismo
Un mecanismo es la implementación que realiza una operación, como la comprobación de límites y la suma de una base por parte del hardware en los accesos a memoria.
Cambiar la regla de selección de huecos no requiere sustituir el mecanismo de traducción por hardware.
Mejor ajuste
El mejor ajuste selecciona el bloque libre más pequeño que sea suficientemente grande para una solicitud, lo que limita el sobrante inmediato, pero a veces crea fragmentos diminutos.
Para huecos de 60, 28 y 44 bytes, una solicitud de 25 bytes toma el hueco de 28 bytes con el mejor ajuste.
Montículo
El montículo es una región de un proceso usada para bloques solicitados durante la ejecución, cuyos tiempos de vida se gestionan mediante asignación y liberación.
Un objeto del montículo puede durar más que la función que solicitó originalmente su almacenamiento.
munmap
munmap elimina una región mapeada del espacio de direcciones de un proceso, a diferencia de devolver un bloque pequeño a una reserva de la biblioteca para reutilizarlo.
Liberar una asignación grande mapeada por separado puede permitir al asignador eliminar el mapeo subyacente.

N

Nodo de lista libre integrado en el bloque
Un nodo de lista libre integrado en el bloque almacena el tamaño y los enlaces de un bloque libre dentro del propio bloque, reutilizando la memoria gestionada para los registros.
Después de dividirse un bloque libre, los primeros bytes de su parte final libre contienen su nodo en lugar de usar una asignación separada fuera del montículo.

P

Peor ajuste
El peor ajuste selecciona el bloque libre más grande para intentar dejar un resto útil, aunque puede consumir un hueco necesario para solicitudes grandes posteriores.
Una solicitud pequeña colocada en el único hueco grande puede hacer que falle la siguiente asignación de mayor tamaño.
Permiso de lectura y ejecución
El permiso de lectura y ejecución permite leer y ejecutar como instrucciones los bytes de una región, mientras deniega las escrituras que los modificarían.
Un segmento de código compartido permite buscar instrucciones, pero rechaza un intento de escribir en sus bytes.
Pila
Una pila es una región usada para el estado de las llamadas a funciones, incluidas las direcciones de retorno y las variables locales ordinarias en el modelo habitual de ejecución.
Retornar de una función libera su marco de pila, pero no libera un bloque del montículo que haya asignado.
Política
Una política es una regla para elegir entre acciones posibles, como qué región física libre debe contener un proceso recién creado.
Elegir el hueco suficiente más pequeño es una política de colocación aplicada por un gestor de memoria.
Primer ajuste
El primer ajuste elige el primer bloque suficiente según el orden de la lista y detiene la búsqueda, por lo que su colocación depende de cómo esté ordenada la lista.
Con huecos de 60, 28 y 44 bytes ordenados por dirección, una solicitud de 25 bytes usa el hueco de 60 bytes.
Puntero colgante
Un puntero colgante es un puntero a un almacenamiento cuyo tiempo de vida ha terminado, como un bloque del montículo ya devuelto al asignador.
Leer mediante un puntero antiguo después de liberar su bloque es un error de uso después de la liberación.

R

realloc
realloc es una función de la biblioteca C que cambia el tamaño de un bloque asignado y puede mover su contenido a un bloque en una dirección distinta.
Un búfer que crece puede moverse cuando su bloque actual no tiene espacio disponible justo después de él.
Redondeo del tamaño de asignación
El redondeo del tamaño de asignación aumenta un tamaño solicitado hasta un tamaño o alineación admitidos, dejando cualquier exceso de capacidad dentro del bloque asignado.
Redondear 21 bytes a un bloque de 32 bytes deja 11 bytes de desperdicio interno.
Región contigua
Una región contigua es un intervalo ininterrumpido de direcciones de bytes vecinas, necesario para un proceso completo con el mecanismo sencillo de base y límite.
Los huecos físicos separados no pueden contener conjuntamente una región que debe ser contigua.
Registro base
Un registro base contiene la dirección física inicial de una región en la reubicación ordinaria hacia arriba, a la que se suman los desplazamientos virtuales válidos.
Con una base física de 12 000, el desplazamiento virtual 200 llega al byte físico 12 200 tras una comprobación satisfactoria.
Registro límite
Un registro límite delimita una región de un proceso y contiene su tamaño en bytes en este modelo; las direcciones virtuales válidas deben ser estrictamente menores que ese tamaño.
Un límite de 4096 permite el byte virtual 4095, pero rechaza un acceso a la dirección virtual 4096.
Reubicación dinámica
La reubicación dinámica traduce direcciones durante la ejecución, lo que permite al sistema operativo mover el almacenamiento físico conservando los valores de los punteros virtuales.
Mover un proceso pausado y cambiar su base hace que sus punteros existentes lleguen a los bytes copiados.
Reubicación estática
La reubicación estática reescribe las direcciones al cargar un programa para ajustarlas a su ubicación física, sin imponer por sí misma protección de acceso a memoria.
Cambiar la ubicación de carga requiere que el cargador reescriba las direcciones incorporadas para la nueva posición.

S

sbrk
sbrk cambia el límite del montículo según un incremento de bytes solicitado y devuelve el límite anterior si tiene éxito; un incremento de cero indica el límite actual.
Una llamada satisfactoria a sbrk(1024) con el límite en 20 000 devuelve 20 000 y deja el nuevo límite en 21 024.
Segmentación
La segmentación traduce las regiones lógicas de forma independiente mediante el estado de cada segmento, permitiendo que la ubicación física difiera de la organización virtual.
Un espacio virtual de 16 KB puede usar solo 7 KB de memoria física para sus tres segmentos utilizados actualmente.
Segmentación de grano fino
La segmentación de grano fino divide un espacio de direcciones en muchas regiones más pequeñas protegidas de forma independiente y descritas mediante una tabla de segmentos.
Una estructura de datos independiente puede tener sus propias reglas de compartición y acceso en un diseño de grano fino.
Segmentación de grano grueso
La segmentación de grano grueso divide un espacio de direcciones en unas pocas regiones grandes, normalmente código, montículo y pila, con estados de traducción separados.
Un pequeño grupo de pares de registros de segmento puede describir la organización clásica de un proceso en tres regiones.
Segmento
Un segmento es una región lógica contigua de un espacio de direcciones con estado de traducción independiente, como una región de código, montículo o pila.
El segmento del montículo puede moverse sin exigir que el segmento de código se mueva a una ubicación física cercana.
Selección implícita de segmento
La selección implícita de segmento elige el estado de traducción según la forma en que se creó una dirección, como una búsqueda de instrucción o el uso del puntero de pila.
Una búsqueda de instrucción usa la traducción del código sin necesitar un campo explícito de número de segmento en su dirección.
Selector de segmento
Un selector de segmento identifica qué estado de traducción de segmento se aplica a una dirección virtual explícita, por separado de su campo de desplazamiento.
En una división de catorce bits, los bits iniciales 01 pueden seleccionar el montículo mientras los doce bits inferiores localizan su byte.
Siguiente ajuste
El siguiente ajuste busca un bloque suficiente desde una posición guardada y recorre la lista volviendo al comienzo, en lugar de reiniciar la búsqueda al principio.
Comenzar una búsqueda de siguiente ajuste en el tercer hueco de una lista en lugar de en el primero puede cambiar su elección incluso cuando los tamaños libres no han cambiado.

T

Tabla de segmentos
Una tabla de segmentos almacena información de traducción y protección para muchos segmentos, lo que permite más regiones que unos pocos pares de registros fijos.
La segmentación de grano fino consulta en una tabla la base, el tamaño y los controles de acceso de cada región seleccionada.
Transparencia
La transparencia es la propiedad que permite a un programa usar su propia vista de memoria sin gestionar la ubicación física ni la compartición que la sustentan.
Un proceso conserva los mismos punteros virtuales después de que el sistema operativo reubique su memoria física.

U

Unidad de gestión de memoria
La unidad de gestión de memoria es el hardware del procesador que traduce direcciones virtuales y comprueba las reglas de acceso mediante el estado instalado por el sistema operativo.
La MMU traduce una búsqueda de instrucción sin llamar a una rutina del sistema operativo para cada instrucción.

Sobre esta unidad

Por StudeliInformar de un error

Crea tus propios Materiales de Estudio

Convierte tus notas, diapositivas y documentos en Guías de Estudio, Preguntas de Práctica, Flashcards y 6 herramientas más.

Comenzar