Resumen: técnicas prácticas para controlar y reciclar memoria en procesos PHP de larga ejecución (queues, daemons, RoadRunner/Swoole) y mantener la huella de memoria estable.
Introducción
Los workers PHP de larga ejecución (colas, daemons, RoadRunner, Swoole) tienden a crecer en memoria con el tiempo: referencias no liberadas, objetos grandes retenidos y fragmentación del gestor de memoria provocan aumento del RSS y degradación del rendimiento.
Este artículo condensa estrategias prácticas para reciclar memoria sin recurrir a reinicios agresivos por defecto: límites controlados, limpieza explícita y patrones de procesamiento que reducen la presión de memoria.
- Referencias retenidas en closures y objetos con referencias circulares.
- Variables estáticas que acumulan cachés ilimitados.
- Procesamiento en lotes demasiado grandes (arrays/objetos en memoria).
- Fragmentación interna del gestor de memoria de Zend o fugas en extensiones (ej.: pdo_mysql).
Prerrequisitos
Antes de aplicar estas técnicas asegúrate de tener control sobre la ejecución del worker y acceso a las extensiones/funciones necesarias.
- PHP CLI con soporte para pcntl si vas a implementar reinicios controlados.
- Capacidad de supervisión/respawn (supervisor, systemd, o el propio orquestador de RoadRunner/Swoole).
- Acceso a herramientas de monitorización (ps, pmap, logs de memoria).
Desarrollo
Procedimiento
- Establecer límites y reinicios controlados.
- Eliminar referencias y forzar recolección de ciclos.
- Procesar en chunks para evitar picos de memoria.
- Reutilizar objetos pesados (pooling) en vez de recrearlos constantemente.
- Monitorizar tendencias y métricas de uso de memoria.
A continuación ejemplos de implementación de cada punto crítico.
1) Reinicio controlado: comprobar uso de memoria y salir para que el supervisor recree el proceso.
<?php
// dentro del loop principal del worker
if (memory_get_usage(true) > 256 * 1024 * 1024) {
// salir para que el supervisor o manager respawnee un proceso limpio
exit(1);
}
Lenguaje del código: PHP (php)
2) Limpieza explícita de referencias y recolección de ciclos: unset no siempre basta si existen referencias circulares.
<?php
// después de procesar una tarea pesada
unset($largeStructure);
// forzar recolección de ciclos si hay objetos con referencias circulares
gc_collect_cycles();
Lenguaje del código: PHP (php)
3) Chunking: evitar cargar datasets completos en memoria. Procesa por lotes y libera cada lote.
<?php
foreach (array_chunk($rows, 5000) as $chunk) {
process($chunk);
unset($chunk);
gc_collect_cycles();
}
Lenguaje del código: PHP (php)
4) Reutilización (pooling): evita crear y destruir objetos pesados frecuentemente. Mantén conexiones o parsers en pool cuando sea seguro.
5) Monitorización: usa herramientas del sistema y funciones internas para trazar tendencias de memoria y detectar fugas tempranas.
ps -o pid,rss,cmd -C php
# o para inspección puntual de PID
pmap <PID> | tail -n 1
Lenguaje del código: Bash (bash)
Ejemplos
Ejemplo de loop de worker que combina chequeo de memoria, chunking y recolector de ciclos.
<?php
// worker.php - bucle simplificado
while (true) {
$rows = fetchPendingRows(50000); // pseudocódigo
foreach (array_chunk($rows, 5000) as $chunk) {
process($chunk);
unset($chunk);
gc_collect_cycles();
}
// chequeo de memoria: salir si supera 256MB para que el supervisor reinicie
if (memory_get_usage(true) > 256 * 1024 * 1024) {
exit(1);
}
// dormir o esperar por nueva tarea
usleep(100000);
}
Lenguaje del código: PHP (php)
Checklist
- Habilitar y probar reinicios controlados (pcntl o supervisión externa).
- Identificar y eliminar referencias circulares; usar gc_collect_cycles tras tareas pesadas.
- Procesar en chunks y liberar cada lote explícitamente.
- Reutilizar objetos pesados mediante pooling cuando sea seguro.
- Registrar y monitorizar memoria (memory_get_peak_usage, ps, pmap) para detectar tendencias.
Trata la memoria como una moneda: mézclala, recíclala y no la derroches en procesos de larga vida.
Conclusión
Workers PHP de larga ejecución son útiles, pero requieren disciplina: límites claros, limpieza explícita y monitorización. Implementa reinicios controlados, limpia referencias, procesa por chunks y registra tendencias para mantener la huella de memoria saneada.
Si no tienes información para afirmar compatibilidades o comportamientos específicos de versiones en tu entorno, prueba primero en un entorno de staging y mide antes de aplicar en producción.

