Automatic Reference Counting (ARC) es una forma de gestión automática de memoria que opera contando el número de referencias 'fuertes' a un objeto. Cuando se crea una nueva referencia fuerte a un objeto, su contador de referencias se incrementa; cuando una referencia fuerte se destruye o se reasigna, el contador se decrementa. Cuando el contador de referencias de un objeto llega a cero, significa que ya no hay referencias fuertes apuntando a él, y el objeto es automáticamente desasignado de la memoria. A diferencia de un Garbage Collector (GC) tradicional, ARC no pausa la ejecución del programa para buscar y liberar memoria, sino que distribuye el trabajo de gestión de memoria a lo largo del ciclo de vida del programa.
ARC es una característica central en el ecosistema de Apple, siendo implementado en Objective-C y Swift. En Objective-C, fue introducido en iOS 5 y macOS 10.7 Lion, reemplazando la gestión manual de memoria (Manual Reference Counting o MRC) que requería llamadas explícitas a `retain`, `release` y `autorelease`. Swift, desde su concepción, ha utilizado ARC como su mecanismo principal de gestión de memoria. Otros lenguajes y entornos, como Rust, utilizan un concepto similar de 'ownership' y 'borrowing' que, aunque no es idéntico a ARC, también gestiona la memoria de forma determinista sin un Garbage Collector.
Para un arquitecto de sistemas, ARC es crucial porque ofrece un equilibrio entre la eficiencia de la gestión manual de memoria y la conveniencia de la gestión automática. Elimina gran parte de la carga de errores de memoria (como 'memory leaks' o 'use-after-free') asociados con la gestión manual, sin introducir las pausas ('stop-the-world pauses') que pueden afectar la latencia y el rendimiento en sistemas con Garbage Collectors. Sin embargo, los arquitectos deben ser conscientes de los posibles 'retain cycles' (ciclos de referencia fuertes) que pueden ocurrir si dos o más objetos se referencian mutuamente de forma fuerte, impidiendo que sus contadores de referencias lleguen a cero y resultando en 'memory leaks'. La mitigación de estos ciclos requiere el uso de referencias 'weak' o 'unowned', lo que añade una capa de complejidad al diseño de la arquitectura de objetos, especialmente en sistemas concurrentes o distribuidos donde la vida útil de los objetos es crítica.