Hi there, I often here the term "garbage collection" and would just like to hear exactly what it means.
That's the act of searching for memory that no longer has any references to it and returning it to the free memory pool.
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?
Code (csharp): void Start() { var data = new int[1000]; } We have created some data - we no longer use it. Garbage collection gets rid of it for us.
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?
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?
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.
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)
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.
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): var blocks = new Block[10]; for (int j = 0; j <= blocks.Length; j++) { blocks[j] = new Block(...); } 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): struct Block { ... } var list1 = new ArrayList(1000); var list2 = new List<Block>(1000); for (int j = 0; j <= 1000; j++) { list1.Add(new Block(...)); list2.Add(new Block(...)); } 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.
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?
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): var timer = new Stopwatch(); timer.Start(); GC.Collect(); timer.Stop(); 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.