Comprender la liberación automática en Objective-C
Este artículo es el anterior: Comprender la extensión y el complemento de ARC en Objective-C
El sistema operativo implementa una fábrica de subprocesos llamada grupo de subprocesos y un administrador cooperante es llamado centro de despacho. El sistema iOS no tiene una interfaz para operar directamente el grupo de subprocesos. La creación, programación y destrucción de subprocesos se deja completamente en manos del grupo de subprocesos. Cuando intentamos crear un subproceso, el centro de despacho lo verificará. el estado de ejecución del grupo de subprocesos, el número de subprocesos en ejecución y la estrategia de ejecución determinan el siguiente proceso de ejecución, ya sea solicitar la ejecución del subproceso directamente o colocarlo en la cola del búfer. Cuando se ejecuta, el grupo de subprocesos decide si. para crear un nuevo hilo o reutilizar el hilo inactivo existente. Los hilos que están inactivos se reciclarán (generalmente alrededor de 10)
El sistema operativo iOS está equipado con un conjunto de estructuras de datos para la ejecución de subprocesos, una pila, un autoreleasePool, un runloop (carga diferida) y algunos para controlar la variable de bandera de estado
Bien ~ volvamos al problema en sí
Hablemos primero de la conclusión:
Veamos la demostración nuevamente, aquí solo analizamos el hilo no principal:
Creé una cola en serie como arriba, escribí un bucle infinito y seguí creando cadenas en el área del montón. pero la memoria no aumentará ni un poquito. El motivo se mencionó en el artículo anterior Comprensión de ARC en Objective-C. Este objeto se liberará directamente y no se agregará al autoreleasePool
Modificar:
Descubrirá que la creación de un objeto de liberación automática mediante un hilo no principal hará que la memoria aumente sin cesar hasta OOM
p>Modificar nuevamente:
El resultado es que la memoria no aumentará en absoluto. Los datos solo corresponden a la conclusión anterior. Para aquellos que quieran saber el motivo, pueden leerlo a continuación.
El artículo del mayor es muy bueno. Un breve análisis basado en el código fuente más reciente (puede que no sea el código fuente más reciente, la versión objc4-781.2 cuando el autor comenzó a leer el código fuente. Por cierto, le diré cómo verificar el código fuente). Enlace del código fuente
Encontrará que AutoreleasePoolPage es una clase C que hereda AutoreleasePoolPageData. La implementación específica es muy larga y algunas implementaciones de funciones se omiten aquí
Todavía es muy larga, pero. es importante comprender el principio. Eche un vistazo a los comentarios de Apple
/***************************. *********************************************
Implementación del grupo de liberación automática
El grupo de liberación automática de un subproceso es una pila de punteros.
Cada puntero es un objeto a liberar o POOL_BOUNDARY, que es
un Límite del grupo de liberación automática.
Un token de grupo es un puntero al POOL_BOUNDARY para ese grupo. Cuando
se abre el grupo, se libera cada objeto más caliente que el centinela.<
/p>
La pila se divide en una lista de páginas con doble enlace. Las páginas se agregan
y se eliminan según sea necesario.
El almacenamiento local de subprocesos apunta a la página activa. , donde se almacenan los objetos recién liberados automáticamente
.
**************************** **************************************/
/* ************************************************** *** **********************
Implementación del grupo de liberación automática
El grupo de liberación automática del hilo es una serie de declaraciones en el puntero de la pila.
Cada puntero es un objeto que debe liberarse o un POOL_BOUNDARY, que es el
límite del grupo de liberación automática.
El token es un puntero al POOL_BOUNDARY del grupo. Cuando
se expulsa la piscina, se libera todo objeto más caliente que el centinela.
La pila se divide en una lista doblemente enlazada de AutoreleasePoolPage. Las páginas se agregan
y se eliminan según sea necesario.
Encadene los puntos de almacenamiento local a la página del punto de acceso donde se encuentran los datos más recientes almacenados en el grupo de liberación automática.
******************************************* ***************************/
Después de leer esta nota, ¿creo que no es necesario continuar? , Una palabra, clara y completa
El siguiente puntero sirve como cursor y apunta a la siguiente posición del objeto de liberación automática que se agregó recientemente en la parte superior de la pila cuando se agrega un nuevo objeto a la. autoreleasePool, se obtiene la dirección del siguiente puntero y se almacena el siguiente puntero. Mueva 8 bytes hacia la parte superior de la pila
Cada autoreleasePool se vinculará al hilo actual cuando se inicialice. la función de inicialización de AutoreleasePoolPage
El primer parámetro es el identificador de AutoreleasePoolPage. El segundo parámetro es un puntero de función. Esta función se ejecutará antes de que salga el hilo, que es tls_dealloc.
Antes de que el hilo entre en suspensión, runloop llamará a objc_autoreleasePoolPop. Excepto por el primer paso, el proceso anterior es el mismo.
¿Está bien unidireccional? Sí, pero la velocidad de consulta disminuirá exponencialmente. ¿Qué debo hacer si elimino la penúltima página que quiero eliminar después de eliminar la página superior de la pila? Recorrala desde el principio, n-1 veces y luego n-2. veces... ...
Entonces, ¿por qué está diseñado como una lista enlazada de dos vías, que es altamente eficiente, eso es todo?