c# – The behavior of the garbage collector in relation to structures


I recently read an article Marginal Performance: C#

Because structures are stored on the stack, they do not require garbage collection.

please explain, is this true?


Summary. No, structures are not necessarily stored on the stack, but objects are not necessarily stored on the heap. Yes, with good chances the structure will still go on the stack. No, you should not count on it, use it and try to optimize in this way.

In fact, you should understand a simple thing: allocating a variable on the stack is cheaper, since it can be easily destroyed without being included in the garbage collection cycle. The only real benefit is this. (Allocation either on the stack or on the heap is nothing more than an increment of one pointer, it is very fast.)

Obviously, the optimizer will allocate on the stack those variables that it can prove are not needed after the death of the current frame. You can often prove this about structures, but not always. For example, a struct may be part of a class object, and must die with the class. Or the method will be implicitly rewritten in continuation style, for example if it is a generator ( yield return & Co.) or a Task<> with async/await. Or the variable got into the closure of some lambda function. Etc. But usually structures are not needed after method execution, so the optimizer can push them onto the stack.

On the other hand, it can also be argued about some objects that they are not needed after the end of the frame – and then the optimizer also has the full right (but not the obligation, of course) to place them on the stack as well.

Pay attention to this subtlety: if you return a structure from a method, you are actually returning a copy of it, so the structure you were working with may end up on the stack. This is not the case with classes: they are not copied by value, but by reference, so the returned object outlives the function that created it, and therefore has no right to live on the stack.

Used materials from the blog of Eric Lippert, to which there was a link above.

I'll add a couple more quotes from Eric:

Using the stack for local struct variables is just an optimization that the CLR does for you. An essential feature of structures is the semantics of copy by value, and not at all that in some cases their destruction can be optimized by the runtime library.

In the vast majority of programs, allocating and destroying local variables will not be a performance critical factor.

Turning a type that should actually be a reference type into a struct is a nano-optimization, with a couple of nanoseconds gain, and probably not worth it. If I were you, I would only do this kind of optimization if the profiling data shows that there is a real, big problem with your real clients that can be fixed using structs. Without such data on hand, I would always choose between classes and structs based on whether the type semantically represents a value or a reference to something. ( That is, does the object have a meaning in addition to the value contained in it, does it have an independent entity – VladD)

Scroll to Top