Fields of class, are they stored in the stack or heap?

Mirek picture Mirek · Apr 2, 2010 · Viewed 16.2k times · Source

I saw a question yesterday which raised (for me) another question. Please look at the following code:

public class Class1
{
   int A; //as I uderstand, int is value type and therefore lives in the stack
}

class Class2
{
    Run()
   {
       Class1 instance1 = new Class1();
       instance1.A = 10;  //it points to value type, but isnt this reference (on heap)?
   }
}

Or while creating the instance of Class1, its field types are created on the heap as well? But then I do not understand when it would really be on the stack as almost always you need to create an instance of object in order to use it fields.

Answer

Eric Lippert picture Eric Lippert · Apr 2, 2010

as I understand, int is value type and therefore lives in the stack

Your understanding is incorrect. Value types are called "value types" because they are copied by value. Reference types are called "reference types" because they are copied by reference. It is not at all true that "value types always live on the stack". If that were true, they would be called "stack types" and "heap types".

The truth is that this is an implementation detail. Different framework implementations can choose to use the stack and the heap as they like. Here's how the Microsoft implementation does it:

  • the value of a variable of reference type is a reference to heap memory. A reference is basically a 32 bit or 64 bit integer.
  • the value of a variable of value type is its value.
  • the values of local variables are stored on the stack unless the local variables are in an iterator block or are closed-over outer variables of an anonymous method or a lambda expression. In those cases the values of local variables are stored on the heap. Unless of course the local variables can be optimized away, in which case there is no storage at all. Or perhaps they can be enregistered, in which case they are neither on the stack nor the heap, they are in processor registers.
  • the values of instance variables of reference types and static variables are stored on the heap.

Is that clear?

it points to value type, but isn't this reference (on heap)?

The field "A" is of value type. It is a field, and therefore that variable is stored on the heap.

while creating the instance of Class1, its field types are created on the heap as well?

The storage for the instance variables is on the heap, yes.

But then I do not understand when it would really be on the stack as almost always you need to create an instance of object in order to use it fields.

It would never be on the stack. As I said above, the only things that go on the stack are local variables (and compiler-generated temporaries) that are not closed-over locals of a lambda or anonymous method and are not in an iterator block. And of course, the jitter is free to keep them off the stack entirely and put them in registers if there are free registers.

But really, I have to ask, why do you care what goes on the stack and what goes on the heap? What goes on the stack is stuff we can cheaply put on the stack; everything else goes on the heap.