¿Cómo puedo rastrear los picos de la memory? (Eso es picos con p, no con l).

Tengo una aplicación de quiosco, que básicamente muestra un montón de diapositivas con varios fragments de información sobre ellos. Inicialmente comencé a codificar esto hace más de un año, cuando comencé con el desarrollo de Objective-C y iOS. Me parece que mi estilo de código es mucho más limpio ahora que lo que era, y tengo mucha más experiencia, así que he decidido volver a escribir desde cero.

Ejecuté mi aplicación con el instrumento Asignaciones para ver cuál era el uso de la memory. Teniendo en count que se trata de una aplicación de quiosco, todo debe funcionar sin problemas, sin fugas. (Por supuesto, todas las aplicaciones necesitan funcionar sin pérdidas, pero una aplicación de quiosco lo convierte en un objective aún más importante). Vi algunos resultados interesantes, así que también ejecuté la versión anterior del código.

Al ejecutar la versión anterior del código, veo una ejecución bastante similar en alnetworkingedor de 1,15 megabytes de uso de memory. Todo parece ser asignado y desasignado según sea necesario. En mi nueva implementación, sin embargo, estoy viendo algo un poco diferente. El uso de la memory sigue saltando en pequeñas "mesetas" y, finalmente, parece alcanzar un máximo de aproximadamente 1,47 megabytes de uso. Esto es lo que parece el nuevo informe de Asignaciones después de ejecutarse durante más de 10 horas:

introduzca la descripción de la imagen aquí

Me preocupa por varios motivos.

  1. El patrón extraño al comienzo de la carrera.
  2. Las asignaciones parecen alcanzar un máximo de 1,47 megabytes, pero ejecutarlo durante la noche muestra que, de hecho, utilizará lentamente más y más memory a lo largo del time. Eso no puede ser bueno.

Hay varias diferencias notables entre el proyecto antiguo y el nuevo.

  • El más antiguo usa Plists como una tienda de respaldo (leo y escribo manualmente en un file Plist). El nuevo proyecto usa Core Data.

  • El nuevo proyecto implementa una biblioteca que se invoca en cada "diapositiva" que el proyecto anterior no tenía. Estaría más preocupado por esta biblioteca, excepto que lo escribí y lo revisé para asegurarme de que estaba liberando todo y solo autoreaba allí donde los lanzamientos manuales eran imposibles.

  • Ambas classs usan una class de fábrica para crear las diapositivas. En el antiguo proyecto, la class de fábrica era única. Pensé que convertirlo en una class normal ayudaría con los problemas de memory, ya que el singleton nunca se lanzó. (Por lo tanto , sus properties no se publicaron. En el nuevo proyecto, se está lanzando la class de fábrica, por lo que no estoy seguro de por qué sigue ocupando toda esa memory (si eso es lo que está causando el problema.

  • El antiguo proyecto usa constantes de cadenas en varios lugares. El nuevo código utiliza una enumeración masiva para la misma cosa. (El nuevo código en general usa más constantes).

¿Qué puedo hacer para rastrear los picos de la memory? La aplicación limpia la memory cuando descarta lo que está usando, pero no parece descartar nada hasta que la aplicación finaliza.

Le agradecería que alguien me ayudara a señalarme en la dirección correcta.

Editar:

Parece que el pico está siendo causado por llamadas a la biblioteca KosherCocoa . Si a alguien le importara echarle un vistazo y decirme qué estoy haciendo mal allí en lo que respecta a la gestión de la memory, realmente lo agradecería.

¿Qué puedo hacer para rastrear los picos de la memory? La aplicación limpia la memory cuando descarta lo que está usando, pero no parece descartar cosas.

Este es un caso clásico de "objects abandonados" o "acumulación de uso". Es decir, tiene una aplicación que, mientras se ejecuta, genera un gráfico de objects en la memory como parte normal del uso. Los objects no se filtran porque todavía están conectados al gráfico de object activo. Lo más probable es que los objects formen parte de algún tipo de caching (un caching de solo escritura, más a menudo) o un mecanismo que involucre un estado histórico (la stack de deshacer es una fuente potencial de acreción).

Para solucionarlo, debes asegurarte de que el gráfico de object se poda de forma adecuada a medida que se ejecuta la aplicación. Las cachings generalmente deben usar un algorithm de poda [LRU] less usado recientemente que limite el tamaño del caching. Si una key de caching nunca es inválida, esa información también debe podarse.

Para información histórica, podar la historia es fundamental. Entonces, se asegura de que los datos históricos contengan una representación absolutamente mínima de ese estado histórico.

Utilice el análisis Heapshot: fue creado para ayudar a localizar exactamente este tipo de problemas.

Escribí una guía detallada de "Cómo"; ¿Cuándo una filtración no es una filtración?