El consumo de memoria es un indicador de rendimiento crítico, y es especialmente importante en plataformas con recursos limitados de memoria, como dispositivos móviles de gama baja.
El diagnóstico de problemas de memoria en Unity se realiza mejor con una herramienta de visualización de memoria de código abierto disponible en Unity’s Bitbucket. La integración de esta herramienta es tan simple como descargar el repositorio vinculado y colocar la carpeta Editor incluida en un proyecto.
La herramienta se puede usar con cualquier versión de Unity desde 5.3 en adelante. Puede capturar una gran cantidad de información sobre el consumo de memoria de código administrado nativo y cuando se adjunta a una aplicación creada con IL2CPP.
Para usar la herramienta, simplemente construya un proyecto con un back-end de scripts IL2CPP y despliéguelo en el dispositivo apropiado. Adjunte el perfilador de CPU en el editor regular de Unity, luego abra la ventana del Perfilador de memoria (menú: Window__> MemoryProfilerWindow) y selet Take Snapshot__.
La aplicación en el dispositivo se detiene brevemente a medida que los datos se recopilan y se transmiten al Editor de Unity. Luego, el Editor de Unity hace una pausa para analizar los datos recibidos; esto puede requerir una cantidad de tiempo significativa. Para aplicaciones muy intensivas en memoria, un rastreo puede requerir de 10 a 30 minutos para analizarse.
Durante esta operación de análisis y carga, se recomienda paciencia.
Esta captura de pantalla proviene de una escena de activos estándar que se ejecuta en un dispositivo con iOS, y muestra que más de las tres cuartas partes del uso de memoria se debe a cuatro texturas muy grandes, todas relacionadas con el fuselaje de la aeronave.
Esta visualización se puede ampliar. Haga clic en cada cuadro en la aplicación para ver más información al respecto.
Un problema de memoria común es la duplicación de los assets en la memoria. Como las texturas suelen ser los activos más intensivos en memoria en un proyecto, la duplicación de textura es uno de los problemas de memoria más comunes que se encuentran en los proyectos de Unity.
Los assets duplicados se pueden identificar ubicando dos objetos del mismo tipo y del mismo tamaño, que parecen haber sido cargados desde el mismo activo. En el panel de detalles del nuevo Analizador de memoria, examine los campos Name y InstanceID de los objetos aparentemente idénticos.
El campo Name se basa en el nombre del archivo de Asset desde el cual se cargó el objeto; generalmente, es el nombre del archivo sin la ruta o extensión del archivo. El campo InstanceID indica el número de identificación interna asignado por el tiempo de ejecución de Unity; este número es único durante una única ejecución de un juego de Unity (1).
Este diagrama demuestra un ejemplo simple de este problema. En los lados izquierdo y derecho del diagrama hay capturas de pantalla tomadas del panel Detalle del 5.4 Memory Profiler. Los assets que se muestran en estas capturas de pantalla son dos texturas cargadas por separado en la memoria. Las texturas tienen nombres y tamaños idénticos, lo que sugiere que pueden ser duplicados. Al examinar la carpeta “Assets” del proyecto, se puede determinar que solo hay un archivo de activos llamado wood-floorboards-texture, que apunta fuertemente a la duplicación de activos.
Cada UnityEngine.Object individual en la memoria tiene una ID de instancia única, asignada a ella cuando se crea el objeto. Como estas dos texturas tienen identificaciones de instancia diferentes, es cierto que representan dos conjuntos diferentes de datos de textura que se cargan en la memoria.
Como los nombres de los archivos y los tamaños de los Activos son idénticos, mientras que los ID de las instancias son diferentes, es cierto que estos dos objetos representan una Textura que se ha duplicado en la memoria (NOTA: Si hay Texturas con nombres de archivo idénticos en el proyecto, entonces este juicio no es absoluto, pero aún es muy sugerente cuando se correlaciona con los tamaños de archivo idénticos).
La causa más común de duplicación de texturas y activos en la memoria es la descarga incorrecta de AssetBundles. Consulte la [Guía de mejores prácticas sobre conjuntos de activos] de Unity (http://unity3d.com/learn/tutorials/topics/best-practices/guide-assetbundles-and-resources?playlist=30089) para obtener una descripción de este problema. La sección clave es Administrar activos cargados.
También es posible visualizar la memoria requerida para proporcionar búferes de representación a los efectos de imagen y objetos RenderTexture en el visualizador de memoria.
La captura de pantalla anterior muestra una escena simple con un puñado de efectos de imagen cinematográfica de Unity aplicados. Los efectos de imagen asignan búferes de representación temporal para realizar sus cálculos; en particular, el efecto Bloom asigna varios buffers de tamaño decreciente. Debido a la alta resolución de los dispositivos Retina iOS, estos búferes temporales consumen mucha más memoria que el resto del proyecto combinado.
Tenga en cuenta que un iPad Air 2 se renderiza a 2048x1536; esto va más allá de la resolución de 1080p, a menudo está enfocado en consolas y PC modernas, pero se ejecuta en una tableta. Un búfer de representación temporal de pantalla completa consume un total de 24 o 36 megabytes de memoria, según el formato del búfer. Esto se puede reducir en un 75% reduciendo a la mitad las dimensiones en píxeles del búfer de renderizado. Esto a menudo no degrada significativamente la calidad visual del resultado.
Una forma de optimizar el uso de los búferes de render temporal de Image Effects y otros recursos de la GPU es crear un único efecto de imagen “uber” que realice todos los cálculos dispares a la vez. Al usar Unity 5.5 o posterior, es posible utilizar el nuevo UberFX (disponible desde github, este paquete proporciona un efecto de imagen “uber” configurable que puede realizar todas las operaciones proporcionadas por los efectos de imagen cinematográfica con menos sobrecarga que los efectos de imagen individuales.