Resumen de la experiencia del problema de desbordamiento de memoria de objective-c

El mecanismo de recuento de referencias de uso de memoria de la plataforma iOS y la introducción de un mecanismo de liberación semiautomático; esta diversidad de uso hace que los desarrolladores sean muy propensos a pérdidas de memoria y crecimiento de memoria inexplicable en el uso de memoria; este artículo presentará la plataforma iOS Principios de uso de memoria y trampas de uso; análisis en profundidad del mecanismo de liberación automática; flujo de procesamiento después de una alarma de memoria baja; combinado con ejemplos propios para introducir el registro de seguimiento de problemas de aumento de memoria y el uso de herramientas relacionadas; 
problemas 
de memoria comunes de la plataforma iOS como desarrollador de la plataforma iOS , ¿Alguna vez ha tenido problemas de memoria? El inexplicable crecimiento continuo de la memoria, el inexplicable bloqueo del programa y las inexplicables pérdidas de memoria son todos problemas comunes relacionados con la memoria de la plataforma iOS; este artículo presentará en detalle el mecanismo de administración de memoria, el mecanismo de liberación automática y las trampas de uso de memoria de la plataforma iOS. Resolverá la mayoría de los problemas en la memoria de la plataforma iOS y mejorará la estabilidad del programa; 
1 Introducción a la gestión de la memoria de la 
plataforma iOS La gestión de la memoria de la plataforma iOS utiliza un mecanismo de recuento de referencias; cuando se crea un objeto utilizando el método alloc o allWithZone, el recuento de referencias es Será +1; cuando se libera un objeto usando el método de liberación, el recuento de referencia es -1; esto significa que cada objeto realizará un seguimiento de cuántos otros objetos se refieren a él, y una vez que el recuento de referencia llegue a 0, se liberará la memoria del objeto; Además, iOS también proporciona un mecanismo de liberación retardada AutoRelease. Los desarrolladores no necesitan liberar manualmente la memoria solicitada de esta manera, y el sistema liberará la memoria en un momento determinado; debido a la diversidad de administración de memoria en la plataforma iOS , Causando que los desarrolladores experimenten fácilmente pérdidas de memoria o fallas inexplicables del programa en el uso de la memoria. Este artículo presentará en detalle las especificaciones y técnicas de uso de la memoria de la plataforma iOS y cómo usar herramientas para evitar o encontrar problemas; 
2 Principios de uso de la memoria de la plataforma iOS 
2.1 Objeto Propiedad y destrucción 
2.1.1 Quién lo creó y lo liberó;
Si el objeto se crea con alloc, new o copy, mutableCopy, debe llamar al método release o autorelease para liberar la memoria; 
si no se libera, causará una pérdida de memoria. 
2.1.2 Quién retiene, quién lo libera; 
si envía un mensaje de retención a un objeto, su recuento de referencia será +1, debe enviar el método de liberación o autorelease para liberar la memoria o restaurar el recuento de referencia después de su uso; 
si no se libera, ¡causará una pérdida de memoria! 
2.1.3 Crear y no retener, no liberar; 
no liberar a aquellos que no son su propia asignación o retener un objeto, o el programa se bloqueará; 
no liberar objetos de liberación automática, de lo contrario el programa fallará; 
la copia profunda y superficial copia el objeto 2.2 
en general Copiar un objeto incluye crear una nueva instancia e inicializar la nueva instancia con los valores del objeto original. Copiar el valor de las variables de instancia que no son de puntero es simple, como booleanos, enteros y números de coma flotante. Hay dos formas de copiar variables de instancia de tipo puntero . Un método se llama copia superficial, que copia el valor del puntero del objeto original en la copia. Por tanto, el objeto original y la copia comparten datos de referencia. El otro método se llama copia profunda, es decir, copiar los datos a los que hace referencia el puntero y asignarlos a la variable de instancia de la copia . 
2.2.1 copia 
profunda El proceso de copia profunda consiste en crear un nuevo objeto y el recuento de referencia de 1, e inicializa el valor del objeto antiguo con el nuevo objeto; 
de ClassA objA * = [[de ClassA the alloc] the init]; 
de ClassA objB * = [objA Copiar];
objB es un objeto nuevo con un recuento de referencia de 1, y los datos de objB son iguales a los datos de objA; 
Nota: objB necesita ser liberado, de lo contrario causará una pérdida de memoria. 
2.2.2 copia 
superficial Los procesos de copia superficial son, sin introducir un nuevo objeto, la referencia del objeto original puede contar + 
de ClassA objA * = [[de ClassA the alloc] the init]; 
de ClassA objB * = [objA The retener]; 
Nota : Es necesario liberar ObjB para restaurar el recuento de referencias de objA; de lo contrario, se producirá una pérdida de memoria. 
2.3 Método 2.3.1 Implementaciones y declaraciones de atributos de acceso a objetos Las declaraciones de 
variables de tipo de atributo común incluyen solo lectura, asignación, retención y copia; y el sistema automáticamente establecerá y obtendrá la función declara una propiedad variable; 
Atributo de solo lectura: solo lectura , No se puede escribir; 
asignar atributo: es el atributo predeterminado, asignar directamente, sin ningún problema de retención y liberación; 
retener atributo: aumentará el recuento de referencias del objeto original y liberará el objeto original antes de asignarlo, y luego realizará la asignación; 
copiar atributo: copias del objeto original, y el objeto antes de la liberación de la asignación original, y luego hacer una asignación; 
2.3.2 usar la declaración de propiedad puede traer riesgos 
cuando las variables que no son puntero retienen (o copian) esta propiedad, intente no ser dominante Suelte esta variable; simplemente deje esta variable en blanco; de lo contrario, la liberación excesiva se producirá fácilmente, haciendo que el programa se bloquee; Por ejemplo: 
el strName de la clase ClassA es una variable de tipo NSString * y el atributo declarado se conserva; 
ClassA.strName = nil; / * Libera el objeto original y asigna nulo a este objeto * / 
[ClassA.strName release]; / * Es posible que se haya liberado la memoria strName, lo que provocará que el programa se bloquee * /
El atributo Assign se usa generalmente para variables que no son puntero (tipo booleano, plástico, etc.); pertenece al tipo de asignación directa y no necesita considerar la retención y liberación de memoria; 
si una variable de tipo puntero usa el atributo tipo asignar, la referencia puede haber sido liberada Variable; hace que el programa se bloquee; Por ejemplo: 
ClassB * obj = [[[ClassB alloc] init] autorelease]; 
…… 
ClassA.strName = obj; / * strName apunta a la dirección de memoria de obj * / 
Cuando se usa ClassA.strName más tarde debido a que obj se libera automáticamente, es posible que se haya recuperado la memoria de obj; conducen a referencias de memoria no válidas, los procedimientos se 
bloquean ; 3 El mecanismo de liberación automática de la plataforma iOS 3.1 libera automáticamente el grupo de preguntas frecuentes 
todo el tiempo en el desarrollo del programa iOS, ya sea que se encuentre en la lista de diapositivas Crecimiento de memoria inexplicable, crecimiento de memoria inexplicable cuando se accede a imágenes con frecuencia, crecimiento de memoria inexplicable cuando las bases de datos se abren y cierran con frecuencia ... Todo esto es gracias al mecanismo de liberación automática de iOS; el análisis específico es el siguiente: 
1: Lista deslizante En ese momento, la memoria ha aumentado inexplicablemente, y las razones pueden ser las siguientes: 
1: El mecanismo de reutilización de UITableView no se usa; hace que cada celda de visualización sea reasignada por liberación automática; hace que la memoria de la celda aumente continuamente; 
se accede a imagen con frecuencia API interna de iOS asignará constantemente búferes de liberación automática para procesar la decodificación y visualización de las imágenes acceso frecuente a las imágenes de red hace que el caché de imágenes alivie este problema; 
2: Cada celda mostrará una UIView separada, y se produce una pérdida de memoria en la UIView, lo que hace que la memoria de la celda crezca continuamente;
2: Cuando se accede con frecuencia a las imágenes, la memoria crece inexplicablemente; 
3: La apertura y cierre frecuentes de SQLite conduce a un crecimiento continuo de la memoria; 
SQLite se abre y cierra con frecuencia, y el búfer de datos para lectura y escritura es grande, por lo que SQLite lo hará Al abrir y cerrar, utilizará la liberación automática para asignar 51K de memoria; si hay muchos tiempos de acceso , la memoria alcanzará inmediatamente decenas de megabytes, ¡o incluso cientos de megabytes! Por lo tanto, en el caso de lectura y escritura frecuentes de la base de datos y un búfer de datos grande, puede configurar el modo de conexión prolongada de SQLite; evitar la apertura y el cierre frecuentes de la base de datos; 
3.2 El concepto de grupo de liberación automática 
NSAutoreleasePool contiene una matriz (NSMutableArray) dentro para guardar el sonido Todos los objetos denominados autorelease. Si un objeto se declara como de liberación automática, el trabajo realizado por el sistema es agregar este objeto a esta matriz. 
ClassA * obj1 = [[[ClassA alloc] init] autorelease]; // retener count = 1, agregar este objeto al grupo de autorelease. 
NSAutoreleasePool mismo atravesará esta matriz cuando sea destruida y liberará cada miembro de la matriz. Si el recuento de retención de los miembros de la matriz es 1, después del lanzamiento, el recuento de retención es 0 y el objeto se destruye oficialmente. Si el recuento de retención de los miembros de la matriz es mayor que 1, después del lanzamiento, el recuento de retención es mayor que 0, el objeto aún no se destruye y la memoria se pierde. 
3.3 El alcance y la anidación del grupo de liberación automática 
AutoreleasePool se puede utilizar anidado.
El grupo está anidado y el resultado del anidamiento es una pila. Solo está disponible la instancia del grupo superior actual del mismo hilo: 
 
cuando se genera un ciclo de vida corto, como un bucle, se generará una gran cantidad de memoria temporal, se puede crear una liberación automática temporal pool, que puede lograr el propósito de recuperar memoria rápidamente; 
3.4 
Creación manual y automática de un pool de liberación automática 3.4.1 Necesidad de crear manualmente un pool de liberación automática 
● Si está escribiendo un programa que no está basado en Application Kit, como una herramienta de línea de comando, no hay Soporte integrado para grupos de lanzamiento automático; debe crearlos usted mismo. 
● Si genera un subproceso esclavo, una vez que el subproceso comienza a ejecutarse, debe crear inmediatamente su propio grupo de liberación automática; de lo contrario, filtrará objetos. 
● Si escribe un bucle en el que se crean muchos objetos temporales, puede crear un grupo de liberación automática dentro del bucle para destruir estos objetos antes de la siguiente iteración. Esto puede ayudar a reducir la huella máxima de memoria de la aplicación. 
3.4.2 El sistema crea automáticamente un grupo de lanzamiento automático 
Application Kit creará automáticamente un grupo de lanzamiento automático al comienzo de un ciclo de evento (o iteración de bucle de evento), como un evento de mouse hacia abajo, y lo lanzará al final del ciclo de evento. 
4 Plataforma iOS trampas de uso de memoria 
4.1 liberación repetida 
se mencionó anteriormente, no liberar el objeto no es para crear uno propio; 
liberar sus objetos de 
liberación automática, la aplicación fallaría ; liberar objetos de liberación automática del sistema, la aplicación fallaría; 
4.2 referencias circulares  
 
circular referencia circular, propensa a referencias salvajes , La memoria no se puede recuperar, lo que eventualmente conduce a una pérdida de memoria. La cadena de referencias circulares se puede romper con referencias débiles; las llamadas referencias débiles no requieren retención y asignación directa. De esta manera, se puede evitar el problema de las referencias circulares, pero se debe tener en cuenta para evitar el problema de la publicación repetida; 
5 iOS Mecanismo de alarma de memoria de plataforma 
debido a iOS El mecanismo de administración de memoria de la plataforma no admite memoria virtual , por lo que en el caso de memoria insuficiente, no creará memoria virtual en Ram ; por lo tanto, una vez que no haya memoria suficiente, la plataforma iOS notificará todas las aplicaciones en ejecución, ya sea una aplicación en primer plano o La aplicación que se cuelga en segundo plano recibirá el aviso de advertencia de memoria; una vez que la aplicación recibe el aviso de advertencia de memoria, debe recuperar las variables que ocupan una gran cantidad de 
memoria ; 5.1 Flujo de procesamiento de alarma de memoria 
1: la aplicación recibe la advertencia de memoria del sistema aviso; 
2: el lanzamiento de la aplicación ocupa una gran cantidad de memoria; 
3: el sistema recupera el objeto de liberación automática creado por esta aplicación; 
4: cuando la aplicación vuelve a la página abierta, el sistema vuelve a llamar al método viewdidload y la vista vuelve a cargar los datos de la página; vuelve a mostrar ; 
5.2 métodos de prueba de alarma de memoria 
en simular para simular mensajes de advertencia de memoria baja; 
Simulador de iOS -> hardware -> advertencias de memoria analógica; los 
desarrolladores pueden simular una advertencia de memoria baja en el teléfono en el caso del simulador, se puede evitar debido a una advertencia de memoria baja El inexplicable problema de bloqueo de la aplicación que conduce a; 
6 Herramienta de verificación de memoria de la plataforma iOS 
6.1 Herramienta de compilación y análisis Analizar
Las herramientas de análisis de iOS pueden encontrar advertencias en la compilación, peligros ocultos de pérdidas de memoria e incluso verificar problemas lógicos; por lo tanto, los problemas encontrados por Analyze deben resolverse durante la fase de autoprueba para evitar errores graves;  
peligros ocultos de la fuga de memoria consejos: 
Fuga potencial de un objeto asignado en línea ……
peligros ocultos de los consejos de asignación de datos: 
El operando izquierdo de …… es un valor basura; Consejos de peligro para referencia de objeto : El 
objeto con recuento de referencia se utiliza después de que se libera; Los 
consejos anteriores son todos serios y pueden causar problemas graves. ¡Los desarrolladores deben prestar mucha atención! 
6.2 Herramienta de detección de memoria 
6.2.1 Herramienta de detección de fugas de memoria: la herramienta de 
fugas de memoria puede contar fácilmente todas las fugas de memoria y también puede mostrar qué línea de código tiene fugas de memoria en ese archivo, para que sea más fácil localizar el problema y también es más aspecto ; Pero cuando Leak cuenta las pérdidas de memoria, también contará la memoria en el modo de liberación automática; por lo tanto, cuando buscamos pérdidas de memoria, podemos ignorar la situación de liberación automática; 
Herramienta de fuga: 
puede encontrar rápidamente la memoria en el código a través de la herramienta de fuga Fugas, a través de herramientas, puede encontrar rápidamente el segmento de código donde se producen las pérdidas de memoria: 
6.2.2 
Herramienta de detección de sobretensiones de memoria : la herramienta de asignaciones de asignaciones puede enumerar fácilmente todos los puntos de memoria asignados , de modo que podamos ordenar por el tamaño de memoria asignado De esta forma, es fácil averiguar qué puntos tienen más memoria asignada y están continuamente asignados, por lo que podemos analizar estos lugares que continuamente asignan mayor memoria;



 
Esta herramienta mostrará todos los lugares donde se aplica la memoria, y contará el número y tamaño de las aplicaciones; de esta lista, puede encontrar los enunciados con más aplicaciones de memoria y las aplicaciones de memoria más grandes; analizando así qué lugares usan más memoria y luego optimizar Y mejora;

Supongo que te gusta

Origin blog.csdn.net/qq_27740983/article/details/50125223
Recomendado
Clasificación