2012-05-13 10 views

Respuesta

21

Al igual que con otras optimizaciones de rendimiento, generalmente solo debe agregar grupos de autorelease adicionales a su código si observa un alto uso de memoria y perfiles (utilizando Instruments, por ejemplo) lo lleva a pools de autorelease adicionales como solución.

Dicho esto, puede ajustar el código que crea una gran cantidad de objetos temporales en un circuito cerrado en un grupo de autorrelease. El grupo de autorrelease predeterminado se drena al final de un ciclo de ciclo de ejecución. Por lo tanto, si está creando muchos objetos temporales en cada iteración de un bucle for en su código, el grupo de autorrelease predeterminado no se agotará hasta que se haya ejecutado todo el ciclo, lo que significa que todos los objetos temporales que crea pueden sumar hasta un alto uso de memoria temporal (a veces llamado "marca de agua alta"). Puede envolver cada iteración del ciclo en @autoreleasepool para hacer que los objetos temporales innecesarios, lanzados automáticamente en esa iteración de ciclo se lancen antes.

+0

Me salvaste. Tengo un método de cálculo de larga ejecución que crea muchos números en varios bucles. En los instrumentos, el uso de la memoria aumenta tremendamente y disminuye una vez que finaliza el cálculo. ¿Hay algún inconveniente al usar '@ autorelease' para envolver bucles individuales? Apple no lo recomienda realmente, ¿verdad? – JFS

+2

Es recomendado por Apple en los casos en que sea apropiado. Consulte la documentación aquí: https://developer.apple.com/library/ios/DOCUMENTATION/Cocoa/Conceptual/MemoryMgmt/Articles/mmAutoreleasePools.html –

+0

Andrew, ¡eres simplemente increíble! Tuve un dolor de cabeza debido a ese problema de memoria hasta que encontré esa sugerencia. Es simple y funciona simplemente increíble. Incluso puedo permitir más cálculos en mi aplicación ahora. ¡GRACIAS! – JFS

1

Todos los objetos liberados automáticamente se colocan dentro de un grupo de autorrelease. Por lo general, hay uno predeterminado creado dentro de su función principal. En cuanto a envolver objetos dentro de un grupo de autorrelease no predeterminado, normalmente se realiza como una optimización.

Normalmente no es necesario utilizar un grupo de autorrelease explícito porque el grupo de autorrelease predeterminado se drena automáticamente dentro del ciclo de ejecución de su aplicación. Sin embargo, si tiene una aplicación que crea muchos objetos liberados automáticamente antes de que regrese de sus manejadores de eventos, puede usar mucha memoria para esos objetos. Por lo tanto, si ajusta su código dentro de un grupo de autorrelease explícito, los objetos liberados automáticamente se colocarán allí en lugar del grupo predeterminado. Esto le permite vaciar periódicamente este grupo para evitar la acumulación de objetos liberados automáticamente.

12

Para amplía las respuestas anteriores:

Una piscina de liberación automática se utiliza para enviar un mensaje release automáticamente a los objetos añadidos a la misma.

En un programa iOS o Cocoa, se crea automáticamente un grupo de autorrelleno en el hilo principal y se drena al final del ciclo de ejecución.

Dicho esto, un grupo de autorrelleno es obligatorio cuando se utilizan objetos de autodesbloqueo en otro hilo.

Por lo tanto, si separa un hilo de algún método, envuelva el código enhebrado dentro de un grupo de autorrellenos. De lo contrario, los objetos de autodesbloqueo creados en el hilo solo tendrán fugas.

Otro uso de un grupo de autodispensas es la optimización de partes del código que utilizarán mucha memoria, por lo que se liberan antes del final del ciclo de ejecución.

Pero solo se trata de objetos de liberación automática.

Por ejemplo:

- (void)test 
{ 
    NSMutableArray * a = [ [ NSMutableArray alloc ] init ]; 

    [ a release ]; 
} 

No hay necesidad de una piscina de liberación automática aquí, ya que no tiene un objeto de auto-editado.
La variable a se liberará inmediatamente, ya que se asignó y liberará explícitamente.

Ahora esto:

- (void)test 
{ 
    NSMutableArray * a = [ NSMutableArray arrayWithCapacity ]; 
} 

Aquí está utilizando un constructor de conveniencia, lo que significa que no tiene la propiedad de ese objeto.
También significa que el objeto se agregó al grupo de autodispensas actual (si hay uno).

por lo que será liberado cuando se drena esta piscina de liberación automático, por lo que podría tomar algunos ciclos ...

Si la parte del código que está escribiendo utiliza una gran cantidad de memoria, es posible utilizar otro piscina autorelease, por lo que sus objetos de auto-editado son liberados cuando sus devuelve el método:

- (void)test 
{ 
    @autoreleasepool 
    { 
     NSMutableArray * a = [ NSMutableArray arrayWithCapacity ]; 
    } 
} 
0

Hay, sin embargo, tres ocasiones en las que podría utilizar sus propios bloques de la piscina autorelease:

  1. Si está escribiendo un programa que no está basado en un marco de interfaz de usuario, como una herramienta de línea de comandos.

  2. Si escribe un bucle que crea muchos objetos temporales. Puede utilizar un bloque de agrupación de autorrelease dentro del ciclo para eliminar esos objetos antes de la próxima iteración. El uso de un bloque de agrupación de autorrelease en el bucle ayuda a reducir la huella de memoria máxima de la aplicación.

  3. Si genera un hilo secundario.

Cuestiones relacionadas