El recolector de basura (GC) es el sistema de administración de memoria interna en PHP, pero hay algunas sutilezas que deben comprenderse.
El GC automatiza la administración de la memoria, lo que elimina la molestia de manejar la memoria con tareas manuales (lo cual sería tedioso).
Esto permite a los desarrolladores centrarse en su lógica empresarial sin preocuparse excesivamente por los errores de "Memoria insuficiente".
Por supuesto, no es magia.
Liberar objetos que ya no son necesarios evita pérdidas de memoria.
El GC utiliza un mecanismo de conteo para determinar los elementos que se eliminarán. Si ninguna referencia apunta a un objeto en particular (es decir, $counter = 0), entonces este objeto es elegible para limpieza.
Funciona bastante bien, pero algunas referencias pueden ser problemáticas:
class A { public $b; } class B { public $a; } $a = new A(); $b = new B(); $a->b = $b; $b->a = $a; unset($a); unset($b);
En este caso de diseño deficiente, PHP no liberará la memoria incluso si desactivamos $a y $b, ya que se hacen referencia entre sí, lo que lleva a PHP a creer que todavía están en uso.
Afortunadamente, existe otro mecanismo llamado Cycle Collector para eso:
gc_collect_cycles();
En términos generales, el recopilador recorre todas las referencias y aplica un algoritmo para marcar los objetos en uso, lo que revela los objetos para recolectar (los que no están marcados).
Sin embargo, PHP no activa la recopilación automática de ciclos hasta que se alcanzan los umbrales de 10,000 objetos con posibles referencias cíclicas.
Nuevamente, no es mágico, por lo que debes invocar gc_collect_cycles() solo en unos pocos casos.
Un mal diseño puede generar relaciones demasiado complejas entre objetos, lo que genera más referencias y una recolección de basura más frecuente.
Cada objeto contado por referencia requiere almacenamiento adicional para su recuento de referencia.
Fuente: Wikipedia - Recuento de referencias
La sobrecarga asociada con las operaciones de limpieza de memoria puede afectar significativamente el rendimiento global y, en última instancia, aumentar el tiempo de ejecución en escenarios específicos.
Hace 10 años, Composer obtuvo un gran aumento de rendimiento simplemente usando la función gc_disable().
Fuente: Composer - deshabilitar GC
De hecho, PHP 7 mejoró drásticamente el GC, por lo que ya no es lo que era en 2014.
Además, las versiones de PHP 8 mejoraron las estrategias de asignación de memoria y agregaron estadísticas más útiles sobre las operaciones de GC para un mejor monitoreo (gc_status() en 8.3).
La mayoría de las aplicaciones PHP funcionan mediante solicitudes y la memoria se borra automáticamente al final de la solicitud.
Nuevamente, es genial, pero no mágico. ¿Qué sucede con las solicitudes asincrónicas y los objetos/demonios de larga duración?
Es posible que experimentes pérdidas de memoria en algún momento.
En este punto, es posible que no veas en qué se diferencia el GC de PHP de otros lenguajes.
La mayoría de las veces, otros lenguajes no dependen del recuento de referencias para recolectar basura o pueden usar implementaciones diferentes.
Por ejemplo, muchos utilizan el algoritmo de seguimiento que también marca los objetos no utilizados pero no funciona de forma incremental. Es un recorrido de gráfico.
Además, algunos lenguajes no permiten dicho control directo (por ejemplo, encendido/apagado en tiempo de ejecución).
Como siempre, existen algunas ventajas e inconvenientes, por lo que es posible que veas algunos enfoques híbridos.
Puedes aprovechar los ayudantes gc_* integrados.
Por ejemplo:
Estas funciones son útiles para depurar o ajustar la recolección de basura cuando sea necesario.
Puedes leer esta publicación para obtener más información:
PHP 7.4 introdujo referencias débiles y PHP 8 introdujo mapas débiles.
Un mapa débil podría describirse como una colección de referencias débiles.
Esta estructura de datos es un almacén de clave-valor versátil que ayuda a PHP a realizar un seguimiento de los elementos sin crear desorden ni consumir espacio excesivo.
Es posible que lo veas como un almacenamiento temporal que se borrará de inmediato cuando ya no sea necesario, ya que no hay ninguna referencia [fuerte] que pueda impedir la recolección de basura:
$object = new stdClass; $map = new WeakMap(); $map[$object] = true; $object->name = 'some name'; print_r($map);// $object is stored in $map unset($object); print_r($map);// $object is cleaned and no longer available
Para la mayoría de los usos, no tendrás que preocuparte por la administración de la memoria, ya que PHP ya la maneja.
Sin embargo, debido a que las pilas modernas utilizan objetos de larga duración, es necesario monitorear su aplicación para detectar posibles pérdidas de memoria.
Si tienes problemas, es posible que tengas que optimizar el código y/o interactuar con el GC directamente.
Descargo de responsabilidad: Todos los recursos proporcionados provienen en parte de Internet. Si existe alguna infracción de sus derechos de autor u otros derechos e intereses, explique los motivos detallados y proporcione pruebas de los derechos de autor o derechos e intereses y luego envíelos al correo electrónico: [email protected]. Lo manejaremos por usted lo antes posible.
Copyright© 2022 湘ICP备2022001581号-3