← Gestión de Memoria Bloque 3 · Asignación contigua · Tema 14 de 52

Tema 14

Simulador de asignación contigua

En este tema unimos las particiones variables (tema 12) y las estrategias de ajuste (tema 13) en un simulador interactivo: un mapa de memoria donde se piden y liberan bloques, se elige la estrategia y se observa cómo se fragmenta el espacio. Al terminar podrás predecir, para cualquier secuencia de peticiones, cuánta fragmentación externa generará cada estrategia.

1. Qué vamos a simular

El simulador gestiona un mapa de memoria lineal dividido en unidades. Cada unidad puede estar libre o asignada a un bloque. Las operaciones son:

El usuario controla el tamaño del bloque pedido, la estrategia y qué bloque liberar.

2. El programa de ejemplo

Este programa en C simula la asignación contigua con las tres estrategias y mide la fragmentación:

contigua.c
#include <stdio.h>
#include <stdlib.h>

#define MEM 64

typedef struct { int inicio, tam, libre; } Bloque;

Bloque mem[MEM];
int nmem = 1;  /* un bloque libre inicial */

void init(void) { mem[0].inicio = 0; mem[0].tam = MEM; mem[0].libre = 1; }

int buscar(int tam, int estrategia)
{
    int idx = -1, best = 9999, worst = -1;
    for (int i = 0; i < nmem; i++) {
        if (mem[i].libre && mem[i].tam >= tam) {
            if (estrategia == 0 && idx == -1) idx = i;          /* first fit */
            if (estrategia == 1 && mem[i].tam < best) { best = mem[i].tam; idx = i; }  /* best fit */
            if (estrategia == 2 && mem[i].tam > worst) { worst = mem[i].tam; idx = i; }  /* worst fit */
        }
    }
    return idx;
}

void asignar(int idx, int tam)
{
    if (mem[idx].tam > tam) {
        /* dividir el bloque */
        mem[nmem].inicio = mem[idx].inicio + tam;
        mem[nmem].tam = mem[idx].tam - tam;
        mem[nmem].libre = 1;
        nmem++;
        mem[idx].tam = tam;
    }
    mem[idx].libre = 0;
}

int main(void)
{
    init();
    int peds[] = {10, 5, 8, 6, 4};
    for (int e = 0; e < 3; e++) {
        init();
        printf("Estrategia %d:\\n", e);
        for (int i = 0; i < 5; i++) {
            int idx = buscar(peds[i], e);
            if (idx >= 0) { asignar(idx, peds[i]); printf("  pedir %d -> asignado\\n", peds[i]); }
            else printf("  pedir %d -> NO CABE\\n", peds[i]);
        }
    }
    return 0;
}

3. El mapa de memoria

El mapa se representa como una barra horizontal dividida en unidades. Cada unidad puede ser:

La barra muestra la fragmentación de un vistazo: muchos huecos pequeños entre bloques asignados indican fragmentación externa.

4. Pedir y liberar bloques

Al pedir un bloque, el simulador busca un hueco según la estrategia y lo divide si es mayor que el pedido. Al liberar, el bloque se marca como libre y se fusiona con los huecos adyacentes (coalescing) para evitar fragmentación artificial.

La compactación (opcional) mueve todos los bloques asignados al principio, uniendo todos los huecos en uno solo.

5. El simulador interactivo

Memoria de 64 unidades. Usa los controles para pedir bloques, liberarlos y cambiar la estrategia.

Simulador · asignación contigua

MedidaValor
Memoria total64 unidades
Memoria usada
Huecos libres
Fragmentación externa (nº de huecos)
Bloques asignados

6. Qué observar

7. Limitaciones del simulador

Este simulador es una simplificación. No modela:

8. En Linux hoy

Linux no usa asignación contigua para la memoria física (usa paginación), pero el asignador del heap (glibc) sí usa variantes de estas estrategias para elegir huecos libres. La compactación del heap (coalescing) se hace automáticamente al liberar bloques adyacentes.

9. Resumen

10. Preguntas de repaso

Intenta responder cada una antes de abrir la respuesta.

1. ¿Qué hace la compactación?

Mueve todos los bloques asignados al principio de la memoria, uniendo todos los huecos en uno solo.

2. ¿Qué es el coalescing?

Fusionar un bloque liberado con los huecos libres adyacentes para formar un hueco mayor.

3. ¿Cuántas unidades tiene la memoria del simulador?

64 unidades.

4. ¿Qué estrategia genera más huecos pequeños?

El mejor ajuste (best fit), porque elige el hueco más ajustado, dejando el resto mínimo.

5. ¿Qué estrategia es la más rápida?

El primer ajuste (first fit), porque se detiene al encontrar el primer hueco válido.

6. ¿Por qué la compactación es costosa?

Porque hay que mover los procesos en memoria y actualizar sus direcciones (base).

7. ¿Se usa la asignación contigua en Linux para la RAM física?

No: se usa paginación, que no requiere bloques contiguos.

8. ¿Qué mide la fragmentación externa?

El número y tamaño de los huecos libres que no pueden usarse para una petición.

Para practicar

  1. Pide bloques de 8, 4, 8, 4 unidades con primer ajuste y observa la fragmentación. Libera el segundo y el cuarto, y pide uno de 6. ¿Cabe?
  2. Repite con mejor ajuste y peor ajuste. ¿Cuál deja menos huecos?
  3. Usa la compactación y observa cómo se unifican los huecos.
  4. Implementa en C la fusión de huecos adyacentes (coalescing) al liberar.
  5. Compara la fragmentación con y sin coalescing tras 10 operaciones.
  6. Investiga cómo glibc fusiona bloques libres adyacentes en el heap.
  7. Dibuja un mapa con bloques de 5, 3, 8, 2 y huecos, y calcula si un bloque de 4 cabe con cada estrategia.