Search Unity

Garbage Collection

Discussion in 'Scripting' started by renman3000, May 23, 2012.

  1. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,697
    Hi there,
    I often here the term "garbage collection" and would just like to hear exactly what it means.
     
  2. cannon

    cannon

    Joined:
    Jun 5, 2009
    Posts:
    751
    That's the act of searching for memory that no longer has any references to it and returning it to the free memory pool.
     
  3. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,697
    Ok,
    Thanks.
    So "searching for memory that it no longer has reference to"...
    Would a good example be, if my wpn shoots at any degree of 360, it is calculated in update, via touch. Obviously the angle can change at any instance, so is garbage an old degree value?


    Also, the "free memory pool", is this just deleting it?
     
    Last edited: May 23, 2012
  4. npsf3000

    npsf3000

    Joined:
    Sep 19, 2010
    Posts:
    3,830
    Code (csharp):
    1.  
    2. void Start()
    3. {
    4. var data = new int[1000];
    5. }
    6.  
    We have created some data - we no longer use it. Garbage collection gets rid of it for us.
     
  5. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,697
    So garbage collection is an actual function? And how should we treat code, make it as simple as possible to ease the job of garbage collection? And does it gc, run by after ecery function? Sorry, just trying to figure out the inner workings.


    Edit.
    I guess what i am vetting at is why should we be concerned with gc and how we should use code to optimize. Is it as simple as using ints over strings?
     
    Last edited: May 23, 2012
  6. kablammyman

    kablammyman

    Joined:
    Nov 22, 2010
    Posts:
    507
    here ya go, sport

    gc
     
  7. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,697
  8. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,697
    So quick question, should I be concerned with gc and if so, what should I do to insure the best use?


    For example if i can use ints over strings, is this it?
     
  9. angrypenguin

    angrypenguin

    Joined:
    Dec 29, 2011
    Posts:
    15,619
    But the general rule is that you should never call the GC manually.

    If you find yourself in a situation where it's actually necessary, it's probably time to re-design your way out of the hole at a higher level. Only call the GC if you can't do that.

    As for your question about whether an angle gets garbage collected, the short answer is "no, it doesn't", but the long answer is that you need to learn about the stack, the heap, and reference and value types.
     
  10. Jaimi

    Jaimi

    Joined:
    Jan 10, 2009
    Posts:
    6,208
    No, that has nothing to do with it. The more times you use the word "new", the more things get created. At some point, you are no longer using those things you created. The system runs garbage collection for you in the background. Sometimes on another thread, and sometimes in the same thread. It cleans up all the unused data, and returns the memory for use. This can sometimes cause "hiccups" while it is cleaning.

    So, be careful of creating lots of objects. Try to reuse them. You never have to call it manually.

    With that said, there are times where you will want to call it manually. It's bad form, but if you really can't have a hiccup, ever, then you can call it yourself once per "loop", using gc.collect(). This will allow you to determine when the hiccup occurs. Like I said, it's bad form, but there are occasions when you have to do it (e.g. when writing to specific hardware you have so many milliseconds to respond, and if something goes south it's a disaster)
     
  11. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,697
    So basically just do nice clean programming and I will be good.


    I do not forsee me needing to call gc manually. If there is ever an overload of something, I adjust the code. Also, my style of code I never create vars that are only used once ever and forgotten. My games are based on loops so everything is reused over and over. Guess I am enviromentally friendly.
     
  12. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,447
    This is a post I wrote a while ago. I suppose here it might be useful too.


    The only way you can control garbage collector is not to feed it with so much data that it can't process in an appropriate time.

    Garbage collections have two characteristics: frequency and duration.

    Frequency
    Garbage collector runs when it sees the memory is low.

    1) One possible cause is that you keep in memory more data than you really need. Revise your data structures to be sure you don't waste the memory with useless and/or repetitive data. Don't keep the data that consumes much, but can be (re)calculated pretty fast.

    2) Another possible cause is that you allocate too much memory for momentary needs, for example every Update() call. Revise your code in case you could use less temporary arrays and lists, and possibly reuse the same instances of big data structures multiple times.

    Duration
    Here's my understanding of how GC works:

    GC starts from the root and recursively runs through all the objects that have references from other objects. The objects the GC hasn't reached during the scan are declared as dead and will be disposed. So, the more alive objects there are in the heap, the longer the garbage collection takes.

    What you can do to make collections faster, is to reduce the number of objects in the heap: use value types instead of reference types for data storing; built-in arrays instead of Array class; and generic collections instead of non-generic ones as much as you can. For example:

    Code (csharp):
    1.  var blocks = new Block[10];
    2.  for (int j = 0; j <= blocks.Length; j++)
    3.  {
    4.      blocks[j] = new Block(...);
    5.  }
    If the Block type is a class, then this code creates 11 objects in the heap: one array of references to blocks and ten Block class instances.

    If the Block type is a struct, then the code creates only one object ― the array of block values.

    ---
    Another example:

    Code (csharp):
    1. struct Block
    2.  {
    3.      ...
    4.  }
    5.  
    6.  var list1 = new ArrayList(1000);
    7.  var list2 = new List<Block>(1000);
    8.  
    9.  for (int j = 0; j <= 1000; j++)
    10.  {
    11.      list1.Add(new Block(...));
    12.      list2.Add(new Block(...));
    13.  }
    While the generic list stores 1000 blocks as an array of actual Block type values, the ArrayList contains the array of 1000 references to the Block type objects that were boxed and placed in the heap. So you have over 1000 objects in the heap instead of only a few in case of generic list.
     
  13. renman3000

    renman3000

    Joined:
    Nov 7, 2011
    Posts:
    6,697
    Awesome Alexzzzz,
    Thank you, this will xome in very handy.


    Is there a way to monitor Garbage Collection, see what it is removing and when it is on?
     
  14. alexzzzz

    alexzzzz

    Joined:
    Nov 20, 2010
    Posts:
    1,447
    GC.CollectionCount ― monitor this value to know the frequency of garbage collections.

    GC.GetTotalMemory(false) ― this value can tell you how much memory is in use, and, when garbage collection happens, how much garbage just has been collected. UPD: and also how much memory is left occupied, which actually is a more useful knowledge.

    Also you can manually run the following code. It will tell you how much time an average garbage collection takes. If it is about 10ms, everything is probably fine.

    Code (csharp):
    1. var timer = new Stopwatch();
    2. timer.Start();
    3. GC.Collect();
    4. timer.Stop();
    5. Debug.Log(timer.ElapsedMilliseconds + " ms");
    The only way to monitor memory usage in detail, I guess, is to separate the memory intensive code into a standalone library, and to create a .Net executable that uses this library the same way the main Unity application does. If you manage to do so, you can profile the library with any .Net memory and/or performance profiler. However, the biggest problem is that the library shouldn't reference any UnityEngine stuff; if it does, it can't be used with .Net applications.
     
    Last edited: May 23, 2012