- Home /
Memory leak issue
Hi, I have developed the Slot game for Linux and Windows in Unity. Right now the game is in testing phase. The issue is when tester play the game continuously for 5 to 10 hours, Ram of the system increases drastically and sometimes the game is crashing. So please give me the best way to solve the ram issue and crashing issue as well.
I am using following system configuration :
Ram : 8 GB
Processor : Ryzen 3
Answer by Bunny83 · Jul 15, 2019 at 04:30 PM
It's almost impossible to produce an actual memory leak in Unity without messing around with native code allocation. In managed code all memory is managed. Memory that isn't longer referenced will eventually be garbage collected automatically. No managed memory can leak that way. However Unity is not a managed application. There might be objects you have allocated that Unity sill has a reference to which you did not tell Unity to get rid of. Those are not memory leaks since you can still access all those objects. Common errors are constantly creating new Mesh, Texture2D, Material, ScriptableObject instances an never destroying them. Those won't destroy themselfs. They are all tracked standalone objects.
Note that accessing renderer.material or Meshfilter.mesh will create an object specific duplicate of the material / mesh. If you do that on objects which are instantiated / destroyed every time they will get left behind.
One way that might help in most cases is calling Resources.UnloadUnusedAssets from time to time. Though you generally should keep track of what objects you create (direct or indirect) and destroy them when no longer in use. Note that components on gameobjects are not standalone objects. Their lifespan is bound to the gameobject they belong to. Also destroying a gameobject will destroy all child gameobjects as well. However if those might reference other standalone resources which got duplicated, you have to take care of them since you created them through code.
Hi Bunny83, Very well thanks for your answer and I mean it. Now I am sharing you the screenshot of profiler which is the GamePlay continuously played in delay with 1 hour. You can figure out my total system memory usage increasing from 3.14 GB to 6 GB, Only in 1 hour. As you can see my Textures, $$anonymous$$eshes, $$anonymous$$aterials, Animation clips, Assets, Game Objects in Scene and Total objects in scene having very $$anonymous$$or changes. So please give me an idea to balance Total system memory usage, Reserved memory and Allocated memory as well.
One thing more as you have said to use "Resources.UnloadUnsuedAssets" in Game, As I have already used it . **But not in time to time** So where and when I can use "Resources.UnloadUnsuedAssets" time to time ?
[1]: /storage/temp/143107-new.png
This is false. The reason is that:It's almost impossible to produce an actual memory leak in Unity without messing around with native code allocation.
All you have to do to create a memory leak is create two objects that reference each other and delete all other references to them. Since both objects are still referenced, they won't be garbage collected, yet you cant interact with them -> memory leak. Naturally, this can also happen with way more than two objects. This is likely the most common reason for memory leaks. So if you want to make sure that the objects you destroy get garbage collected, remove all its references. (and make sure you don't have any circular referencing in the first place)$$anonymous$$emory that isn't longer referenced will eventually be garbage collected automatically.
You could also cause resource leakage which to all intents and purposes will look like a memory leak especially if you are failing to dispose regularly.
Oh p.s. I dont think circular references are an issue in c# its GC doesnt use reference counting.
Gah sleepy brain
No, this is not true. The garbage collector will detect such cyclic chains without any issues. At least if the garbage collector runs eventually. Feel free to run a test. Create two "normal" .NET objects and let both reference each other through instance fields. Add a destructor / finalizer to your classes which print to the console when they are garbage collected. $$anonymous$$ake sure you don't have any other references to your objects. $$anonymous$$anually run System.GC.Collect()
and you should see both objects being collected.
It's ok not knowing how the GC works, however comments like this are misleading and spreading wrong information.
The only thing you have to take care of are private static references. However it should be obvious if you have a private static reference to an object and you never get rid of that reference that the referenced object will stay forever. Though that's usually the point of having a "singleton". A single static field also can only reference a single object. That object (and all it's references) are still available through the static field. Even when it's private you could use reflection to clear that field. So again: In managed land there is almost no way to create a memory leak. That's one of the main points why we actually have managed memory.
I just created those two classes and the test code in Start:
public class Test1
{
public string name;
public Test2 parent;
public Test1(string aName, Test2 aParent)
{
name = aName;
parent = aParent;
}
~Test1()
{
Debug.Log("Destroyed Test1: " + name);
}
}
public class Test2
{
public List<Test1> childs = new List<Test1>();
~Test2()
{
Debug.Log("Destroyed Test2");
}
}
void Start ()
{
var c = new Test2();
for (int i = 0; i < 100; i++)
c.childs.Add(new Test1("Name_" + i, c));
}
As you can see I create a Test2 instance which is referenced in variable "c". I also create 100 Test1 class instances and each one has a reference to the "parent" Test2 instance. Also Test2 has a List and each of the Test1 instances will be added to that list. Now when the Start method ends the local variable "c" goes out of scope and out of extent. Therefore the reference to Test2 is gone.
If you just wait a few seconds (could take a bit longer), you should see all the finalizers of our classes to run. Please keep in $$anonymous$$d that you can not really "force" the garbage collector to collect an object NOW. When you run GC.Collect all you do if force run a GC cycle. If and when an object and it's memory will be collected depends on the GC implementation.
Another little note: A generic List as I used in my example has an internal array which is referenced through a private internal variable inside the List class. You never ever have direct access to this variable and therefore you can never set it to null manually. Also each of the name strings I create is also a seperate object. The whole object tree will be collected since no there's no "anchor" reference to any of those objects anymore.
Second note: If I would grab any of the Test1 instances (for example c.childs[42]) and store a reference in a member variable of my $$anonymous$$onoBehaviour none of the objects would be collected. Why? Because we still have a reference to that single Test1 instance, so it can't be collected. Since each Test1 instance has a reference to the Test2 parent, it also won't be collected. Since Test2 has a list with references to all other Test1 instances we created, none of them will be collected.
Final note: "Anchor" references are any references that either live in static memory (static variables) or variables which live in the current executing code. Of course any objec that has further references to other objects will keep them alive as well. That's what we call an object tree. However as soon as the root is cut, the tree will "eventually" fall. Again, keep in $$anonymous$$d that the GC will collect the object when it thinks it's appropriate.
Answer by Lawrence57 · Jul 26, 2019 at 09:52 AM
In computer science, a memory leak is a type of resource leak that occurs when a computer program incorrectly manages memory allocations in such a way that memory which is no longer needed is not released. A memory leak may also happen when an object is stored in memory but cannot be accessed by the running code.
Answer by MadsWiering · Jul 15, 2019 at 01:38 PM
Maybe use the deep profiler to locate where you get the memory leak.
Your answer
Follow this Question
Related Questions
[Linux] Bad PInvoke performance in the built application 0 Answers
My Skybox Stopped Working... 3 Answers
Is it possible to use a map editor like Tiled with Unity3D? 0 Answers
Mouse input feels sketchy. Any way to fix? 1 Answer
loading screen usage 2 Answers