Mark-and-Sweep es un algoritmo de Garbage Collection (GC) que gestiona la memoria dinámica de forma automática. Su funcionamiento se divide en dos fases principales: la fase 'mark' y la fase 'sweep'. Durante la fase 'mark', el recolector de basura comienza desde un conjunto de 'raíces' (objetos directamente accesibles por el programa, como variables globales o en el stack) y atraviesa el grafo de objetos, marcando todos los objetos que son alcanzables. Cualquier objeto que no sea alcanzable desde estas raíces se considera basura y es candidato para ser recolectado. En la fase 'sweep', el recolector itera a través de todo el heap de memoria, liberando el espacio ocupado por los objetos que no fueron marcados, haciéndolo disponible para futuras asignaciones.
Este algoritmo es fundamental en muchos entornos de ejecución de lenguajes de programación modernos. Ejemplos concretos incluyen la Java Virtual Machine (JVM), donde es la base de muchos de sus recolectores de basura (como el Serial GC, Parallel GC, y G1 GC en sus fases iniciales), y el Common Language Runtime (CLR) de .NET. También se utiliza en lenguajes como Python (aunque con un sistema híbrido que incluye conteo de referencias y un recolector generacional basado en Mark-and-Sweep para ciclos), Ruby y JavaScript (en sus motores V8, SpiderMonkey, etc.). Su simplicidad conceptual lo hace un punto de partida común para implementaciones de GC más sofisticadas.
Para un arquitecto de sistemas, entender Mark-and-Sweep es crucial debido a sus implicaciones en el rendimiento y la latencia. Una de sus principales desventajas es que, tradicionalmente, es un algoritmo 'stop-the-world', lo que significa que la aplicación debe pausarse completamente durante las fases de mark y sweep. Esto puede introducir pausas significativas (latencia) que son inaceptables en sistemas de alta disponibilidad o baja latencia. Los arquitectos deben considerar si la carga de trabajo puede tolerar estas pausas o si se requieren algoritmos más avanzados como los recolectores generacionales, concurrentes o incrementales (que a menudo se construyen sobre principios de Mark-and-Sweep pero con optimizaciones para reducir el tiempo de pausa). La elección del algoritmo de GC impacta directamente en la capacidad de respuesta del sistema, el throughput y el consumo de recursos, siendo una decisión clave en el diseño de plataformas y servicios.