Unity Board AI memory leak game

I am creating a board game similar to tic tac toe and I created an AI to play this game. AI works very intensively, so I decided to put it in my thread. I use this plugin for multithreading: https://www.assetstore.unity3d.com/en/#!/content/15717 .

I have this 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!"); } 

and I run it with

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

Usually, when I run executeAITurn, it works fine without problems, but for some reason sometimes when I run it, it does what it should, but in the task manager my memory only starts to increase by about 30 mb / s. The memory capacity is increased to 1000 mb, and the game becomes very slow. When I turn off the playback mode, the memory sometimes continues to increase or just stops where it is. I have to finish Unity through the task manager to free up memory.

One thing I have tried is replacing foreach loops with regular loops and it seems to help. The speed with which the memory increased decreased by a lot (initially it increased at a speed of about 100 mb / s).

Any help would be appreciated.

Here are some of the code involved in executeAITurn:

mctsManager Class: https://pastebin.com/yzeHrY2p

input Function: https://pastebin.com/8f2hzZws

+5
source share
4 answers

All the answers to this question really helped me better manage my memory. I just thought that I am summing up big things from each in one question.

First of all, in Robert Livingston's answer, he mentions this article: https://unity3d.com/learn/tutorials/topics/performance-optimization/optimizing-garbage-collection-unity-games , which literally covers everything that helped me. I wish I read it earlier.

In any case, the three biggest things that helped me were to avoid boxing, mailing lists, and caching (all three of which are mentioned in the article). Trying to avoid boxing also led me to explore the differences between value types and reference types, which led me to change my two classes into structures that helped with memory.

The biggest memory aid is probably cleaning the lists, since they were created very often, but I did not clear them, which caused a lot of garbage. (That's why I gave generosity to the one who mentioned the clearing lists).

Anyway, thanks for the help.

+1
source

This is more like a garbage collection problem. I looked at your code for MCTS and noticed the following.

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

This was missing from your first code, the C # input function. This basically calls the update function. As you can see, it says that the update function is called once for each frame. Refer to this https://unity3d.com/learn/tutorials/topics/performance-optimization/optimizing-garbage-collection-unity-games

I would recommend the cache.

Hope this helps.

+3
source

When dealing with memory leaks, you must be very careful, because every step in your application is important.

For beginners, every cycle you have can lead to an increase in memory. Try to reverse the use of loops to work with a dictionary and a hash table, it will cost you โ€œnot on orderโ€ data, because it compares hash codes, but I donโ€™t think you need a certain order for your data in games.

Explanation: Each array list that you have, if you know the exact size of your array, use an ArrayList. If you use a list, switch it to a dictionary if the list type is known to you or a Hash Table if not. this way, you can get key value information that is faster and improves performance.

Secondly, try using the Using syntax when you create a new object, this will help you implement the iDisposable interface to delete objects more efficiently.

Third, protect your code from box variables as much as you can! boxing means the process of storing the type of value on the heap, not on the stack, so on the stack you only have a link to the location of the variable.

Fourth, use tools to monitor your code and check for possible memory leaks in your applications. There are many tools besides the profiler, so just find it and you will find something that will help you.

+2
source

The first task manager is not a valid tool for measuring performance, even memory requirements . The numbers can be either high or low. Perhaps at the same time.

Secondly, the very nature of the Garbage Collector makes measuring how much memory is actually used very difficult. GC will try to run as little as possible. And if it only works when you close the application, this is an ideal case.

If you exclude that this is any of these two common misconceptions, usually a memory leak in a managed Runtime means one thing: you add something to the collection (array, list <>, dictionary <,>), but forget to pull it out again. This is the only way to leak memory. In particular, there is GC, so again we are not faced with the problem "I forgot to free up memory."

A rare case is errors with Disposing . If you pass directly the resources that you use, you must first write your finalizer and then delete the second. If you are processing anythign that implements IDisposeable, always implement IDisposeable as well, even if all of your Dispose () relays the order to the contained instance. Never pass a Finalize order, that is, between this instance and the GC.

+2
source

Source: https://habr.com/ru/post/1271260/


All Articles