Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

How to block unity game's memory leak problem? GC.Collect()?

Discussion in 'Scripting' started by leegod, Oct 29, 2015.

  1. leegod

    leegod

    Joined:
    May 5, 2010
    Posts:
    2,345
    So I made standalone build for windows, run testing, but memory usage of game increasing slightly but forever.

    I made my script as call Destroy to instantiated objects, and after call Destroy, then call GC.Collect();

    But memory usage increasing problem does not solved.

    Why this happen? and how to block it?

    Thanks.
     
  2. martinmr

    martinmr

    Joined:
    Mar 25, 2015
    Posts:
    325
    Have you already used the Profiler to profil your game in unity?
     
    Kiwasi likes this.
  3. leegod

    leegod

    Joined:
    May 5, 2010
    Posts:
    2,345
    I saw profiler's memory tab, but I don't know what to examine from there..
     
  4. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    Well, when you highlight that tab, you'll see a description of what takes up what for memory.

    If you're in 'Simple' mode, it'll just have a general outline of the memory usage.

    You're going to look for the one that is climbing regularly over time without stopping. You're saying that your system memory is getting taken up more and more over time, so you need to find the area that's doing it.

    Once you get a general idea of where it's coming from, then click where it says simple and select 'detailed'. Then click 'Take Sample', and dig into the specifics of it to see what script is the offender... you'll probably have to take multiple samples.

    Get an idea of what is taking up what memory this way.
     
  5. leegod

    leegod

    Joined:
    May 5, 2010
    Posts:
    2,345
    So I checked with DetectLeak script (http://wiki.unity3d.com/index.php?title=DetectLeaks) (v2), my instantiated gameobjects destroyed exactly it should be and DetectLeak's values does not change at all compared with initial values after run the game a while.

    But memory usage still increasing as time goes.

    What can I missing other than gameobject instantiating?

    or is this the problem of Mono's Garbage Collector itself's problem?

    or maybe C# itself's problem?

    (I heard even if I manually called GC.Collect(), actual unity's Garbage collector does not work properly, immediately)
     
  6. hippocoder

    hippocoder

    Digital Ape Moderator

    Joined:
    Apr 11, 2010
    Posts:
    29,723
    This is really well covered with search. Basically, don't allocate. Pool everything.
     
  7. leegod

    leegod

    Joined:
    May 5, 2010
    Posts:
    2,345
    I adopted object pooling system based on free asset on assetstore, so basically in my game nothing is instantiated(once instantiate at start of game only) and destroyed,

    but memory leak problem stand still. What else can I missing?
     
  8. cl9-2

    cl9-2

    Joined:
    May 31, 2013
    Posts:
    417
    Which pooling system are using? There are some memory pools that actually leak memory.
     
  9. leegod

    leegod

    Joined:
    May 5, 2010
    Posts:
    2,345
  10. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    It could be any number of things. What does the profiler indicate?
     
  11. leegod

    leegod

    Joined:
    May 5, 2010
    Posts:
    2,345
    At profiler, memory usage increases.
     
  12. Fajlworks

    Fajlworks

    Joined:
    Sep 8, 2014
    Posts:
    344
    As everyone said, it is impossible to guess what the problem could be. Your best bet would be to enable deep profiling and track GC allocations.


    Just track the highest gc allocation each frame, and descent the tree until you find the function that causes most allocations and start investigating the script.

    Not sure if it causes leaks, but you could check if you are heavily changing colors on your images.
    Code (CSharp):
    1. Image myImage = gameObject.GetComponent<Image>();
    2. myImage.color = Color.cyan;
    If I remember correctly, it would always create a new material, which broke batching. Probably not related to your problem, but who knows? Good luck!
     
    HiddenMonk likes this.
  13. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    Garbage gets collected and thrown out, so that block of memory can be reused. That's why it's called garbage. If you're memory is increasing because of that, it'd be because you're allocating huge chunks of memory simultaneously.

    It's more like an asset that's getting created and not destroyed. Like Fajlworks sugested, a material that might be getting duped.

    When you looked at the profiler memory... it breaks down what is using what memory:
    memory_usage.png
    See how it outlines textures, materials, meshes, mono, unity, etc.

    Which one of these is increasing over time and not stopping increasing? It might be a couple of them increasing because they might be related.

    When you say:

    Yeah, we know that, that's what the original post is about. Give some more detail! Dig into it!
     
    Kiwasi likes this.
  14. leegod

    leegod

    Joined:
    May 5, 2010
    Posts:
    2,345
    Thx.
    So this is shots.

    profiler-simple.PNG

    profiler-detail.PNG

    But still I don't know where is problem.

    I am using object pooling system, so there is no instantiating, destroying. And I manually call GC.Collect() every 30 seconds.

    Anyway, I tried to run this game on Windows 7 64bit, 2Giga ram pc, run well. Memory usage increase, but when it reach full usable memory, it become low again.
    So it seems garbage collector work when memory usage is full.

    If this is true, I don't like this. For stable game running, GC should work periodically, not only when it reaches full usage. But C# can't control this by user maybe? whileas C++ can.
     
  15. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    So one of the things you need to do when you're debugging is consider the possibility that your assumption is NOT what the problem is.

    You keep assuming GC is your problem.

    But take a look at that memory usage there...

    Used Total... Mono: 9.1MB
    Reserved Total... Mono: 68.1MB

    Your program has 68.1 MB allocated of the system memory for your managed code objects.

    Where as... your mesh data is 1.28GB, and your texture data is 1.02.

    That is quite a bit.

    Here's the thing, you also say that your memory usage is GROWING over time. You're showing me a static image. I cant' see what is growing over time. I don't know if your mesh data was smaller last frame, and larger next frame.

    I asked you to look at this, and tell us which item is GROWING.

    But no, you couldn't bother yourself to even consider the possibility of doing anything. It was like pulling teeth just to get you to even OPEN the memory profiler and take a screenshot. But you didn't read it... how I know you didn't read it? You still think it's GARBAGE COLLECTION that's causing your problem. Despite the fact that the mono framework using a mere 2% of your memory!

    And looking at your memory timeline, your GC usage is the lowest line on the timeline, and it's rather constant... with a consistent tick in it that is probably your GC call.

    Nothing appears to be climbing on that curve... and I get a feeling the problem you described in the OP about your memory slowly getting larger and larger isn't accurate. But rather that you just plain out ran out of memory... which you have. You're using 3+ gigs of memory, on a machine with 2 gigs. That would be out of memory. That's not the garbage collector that knocks it low again when you've filled up the memory... That's all the other stuff getting knocked onto disk because memory is full.

    GC collects when that 68.1MB reserved is hit. Not when the TOTAL SYSTEM MEMORY is hit.

    That's not how these things work.
     
  16. leegod

    leegod

    Joined:
    May 5, 2010
    Posts:
    2,345
    Sorry, I didn't know well about GC.

    and of course I monitored profiler, but not seems much increased. I took a video.

     
  17. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    Video is private.
     
  18. leegod

    leegod

    Joined:
    May 5, 2010
    Posts:
    2,345
    made it public
     
  19. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,380
    Yeah, you're memory usage is pretty flat. It consistently remains at a reserved total between 3.04GB and 3.14GB.

    If you're using this on a machine with only 2 gigs of RAM, what will happen is that what memory is being accessed will be copied into RAM from disk, and excess will be copied back to disk... this is SLOW. Don't do it.

    Basically this means your game has a minimum system requirement of 3.5 to 4 gigs of RAM.
     
  20. Kiwasi

    Kiwasi

    Joined:
    Dec 5, 2013
    Posts:
    16,860
    If you want to run on a system with less memory, start dropping the things that take memory. This would involve dropping the complexity of your meshes and reducing the sizes of your textures. Or reducing the number of models. Do you really need 1762 meshes? That's a lot of objects running around.