unity tutoriales tutorial tag score official hacer examples como c# multithreading unity3d memory-leaks

c# - tutoriales - unity tag



Unity Board Game AI Causa pérdida de memoria (4)

El primer administrador de tareas no es una herramienta válida para medir el rendimiento de la demanda de memoria uniforme. Las cifras pueden ser tanto de alta como de baja. Posiblemente al mismo tiempo.

En segundo lugar, la naturaleza misma del Garbage Collector hace que medir cuánta memoria realmente se use sea realmente difícil. El GC intentará correr lo menos posible. Y si solo se ejecuta al cerrar la aplicación, ese es el caso ideal.

Si ha excluido que sea alguno de esos dos conceptos erróneos comunes, generalmente las pérdidas de memoria en un tiempo de ejecución administrado significan una cosa: agrega algo a una colección (matriz, lista <>, diccionario <,>) pero olvida volver a sacarlo . Esa es la única forma en que puede ocurrir una pérdida de memoria. En particular, GC está ahí, así que no nos topamos con el problema de "Olvidé liberar memoria" nunca más.

Un caso más raro son los errores con la eliminación . Si tiene recursos administrados directamente, primero debe escribir el finalizador, Desechar el segundo. Si manejas cualquier cosa que implemente un ID, solo debes implementar ID, incluso si todo lo que Dispose () hace es transmitir el orden a la instancia contenida. Nunca retransmitir una orden de Finalización, es decir, entre esa instancia y el GC.

Estoy creando un juego de mesa similar al tic tac toe, y he creado una IA para jugar ese juego. La IA requiere mucha CPU, así que decidí ponerla en su propio hilo. Estoy usando este complemento para hacer subprocesos múltiples: https://www.assetstore.unity3d.com/en/#!/content/15717 .

Tengo este IEnumerator:

static IEnumerator executeAITurn(Turn turn) { Vector2[] move = mctsManager.mcts(new State(sections, null, turn), AIIterations)[0, 0].metaData.lastMove; yield return Ninja.JumpToUnity; input(move, true); yield return Ninja.JumpBack; Debug.Log("DONE!"); }

y lo ejecuto usando

gameManager.StartCoroutineAsync(executeAITurn((AITurn == Turn.X) ? Turn.O : Turn.X));

Normalmente, cuando ejecuto executeAITurn, funciona normalmente sin problemas, pero por alguna razón, a veces, cuando lo ejecuto, hace lo que se supone que debe hacer, pero en el administrador de tareas mi memoria comienza a aumentar en 30 mb / seg. La memoria aumenta hasta 1000 mb y el juego se vuelve realmente lento. Cuando apago el modo de reproducción, la memoria a veces continúa aumentando o simplemente se detiene donde está. Tengo que finalizar Unity a través del administrador de tareas para liberar la memoria.

Una cosa que he intentado es reemplazar los bucles foreach con loops regulares y eso pareció ayudar. La velocidad a la que la memoria aumentaba disminuyó mucho (inicialmente aumentaría a aproximadamente 100 mb / seg).

Cualquier ayuda sería apreciada.

Aquí hay algunos de los códigos involucrados en executeAITurn:

Clase de mctsManager: https://pastebin.com/yzeHrY2p

Función de entrada: https://pastebin.com/8f2hzZws


Cuando se trata de pérdidas de memoria, debe tener mucho cuidado, porque cada paso en su aplicación es importante.

Para los principiantes, cada ciclo que tienes, puede causar un aumento en la memoria. Intente invertir desde el uso de bucles, hasta trabajar con el diccionario y la tabla hash, le costará datos "fuera de orden", ya que está comparando códigos hash, pero no creo que necesite un cierto orden para sus datos en el juego.

Aclaración: cada lista de matriz que tenga, si conoce el tamaño exacto de su matriz, use ArrayList. Si usa la lista, cambie a diccionario, si conoce el tipo de lista o Hash Table si no. De esta forma, podrá obtener la información de una manera clave-valor, que es más rápida y mejora el rendimiento.

En segundo lugar, intente usar la sintaxis Using cuando crea una instancia de un nuevo objeto, esto lo ayudará a implementar la interfaz iDisposable para deshacerse de los objetos de manera más efectiva.

¡Tercero, evita tu código de las variables de boxeo tanto como puedas! boxeo significa, el proceso de almacenar un tipo de valor en el montón en lugar de en la pila, por lo que en la pila solo se tiene una referencia a la ubicación de la variable.

En cuarto lugar, use herramientas para monitorear su código y verificar posibles fugas de memoria en sus aplicaciones. Hay muchas herramientas, excepto el generador de perfiles, así que simplemente búscalo y encontrarás algo para ayudarte.


Esto suena más como un problema de recolección de basura. Miré tu código para MCTS y noté lo siguiente.

// Use this for initialization void Start () { } // Update is called once per frame void Update () {

Esto faltaba en su primer código, las funciones de entrada C #. Básicamente, esto está invocando una función de actualización. Como puede notar, dice que la función de actualización se llama una vez por cuadro. Consulte este https://unity3d.com/learn/tutorials/topics/performance-optimization/optimizing-garbage-collection-unity-games

Yo recomendaría un caché.

Espero que ayude.


Todas las respuestas a esta pregunta realmente me ayudaron a manejar mejor la memoria. Solo pensé en resumir las grandes cosas de cada una en una pregunta.

En primer lugar, en la respuesta de Robert Livingston menciona este artículo: https://unity3d.com/learn/tutorials/topics/performance-optimization/optimizing-garbage-collection-unity-games , que literalmente cubre todo lo que me ayudó. Ojalá lo hubiera leído antes.

De todos modos, las tres cosas más importantes que me ayudaron fueron evitar el boxeo, las listas de compensación y el almacenamiento en caché (los tres se mencionan en el artículo). Intentar evitar el boxeo también me llevó a investigar sobre la diferencia entre los tipos de valores y los tipos de referencia, lo que me llevó a cambiar dos de mis clases por estructuras, lo que me ayudó con la memoria.

La mayor ayuda para la memoria probablemente fueron las listas de borrado, ya que se creaban con mucha frecuencia, pero no las eliminaba, lo que causaba una gran cantidad de basura acumulada. (Esta es la razón por la cual di la recompensa a la persona que mencionó las listas de compensación).

De todos modos, gracias por toda la ayuda.