Reputation: 36058
Meanwhile reading on the internet I learned that static variables always have the same memory address. So when compiling the program, the compiler is going to decide what memory address to assign to the static variables. Reading that made me think about what happens when you do:
class Foo {}
class Program
{
public static Foo someStaticVar;
static void Main(string[] args)
{
Foo localVariable = new Foo();
int x = 4;
someStaticVar = localVariable; // is someStaticVariable still will have the same address?
}
// variable x will be pushed of the stack
// localVariable will be pushed of the stack
// what happens then with someStatic var?
}
I also learned that when declaring variables inside a method they will be pushed to the stack when created and popped out the stack when the method returns. If all that is true then someStaticVar should disappear but it doesn't.
I am sure I must understood something incorrectly. Or maybe on the line someStaticVar = localVariable;
is performing a deep copy of that object but I doubt it because there are a lot of questions on the interenet on how to do a deep copy of an object and they are much different than this approach.
Upvotes: 4
Views: 3413
Reputation: 1038920
In the example you provided localVariable
is only a local variable to the Main
method. It falls out of scope once the Main method ends executing. But since you have assigned it to the static field, the Foo instance that was created will continue to live outside of the Main method. And since it is static field it will live even outside of the Program class.
So here's what happens step by step:
static void Main(string[] args)
{
// an instance of Foo is created and pushed on the heap
// localVariable is now pointing to the address of this instance
// localVariable itself is stored on the stack
Foo localVariable = new Foo();
// someStaticVar is now pointing to the same location on the heap as
// the localVariable - the Foo instance created earlier
someStaticVar = localVariable;
}
// at this stage the Main method finishes executing and all local
// variables are falling out of scope. But since you have a static variable
// pointing to the Foo instance that was created inside the Main method this
// instance is not illegible for garbage collection because there are still
// references to it (someStaticVar).
If someStaticVar
was an instance field and not static then the same process will happen except that the instance will fall out of scope once there are no longer any references to the containing class (Program).
Upvotes: 4
Reputation: 41
when declaring variables inside a method they will be pushed to the stack when created and popped out the stack when the method returns.
Foo localVariable = new Foo();
will create Foo object on heap, & reference is stored on stack. when method completes, references is removed from stack. Garbage collector will do job of removing Foo from heap as there will be no reference to Foo object. But,
someStaticVar = localVariable;
, will cause, someStaticVar to reference Foo object on heap. Even after method exits, someStaticVar will still be refering Foo object. so, garbage collector wont collect that Foo object. Main thing to remember is , when Reference type's object is created, object is created on heap, & reference is stored on stack.
Questions is "where static field is stored?", object's instance fields are stored on heap, local variables are stored on stacks, but where "static variable exist in memory?"
Upvotes: 2
Reputation: 203834
In this case Foo
is a class, so it is a reference type. A variable of type Foo
is really just a pointer to a location in memory where the Foo
object actually is stored.
When saying that the static variable has a constant memory address it is not saying that the value of that memory address is constant. The address of the pointer to the Foo
object won't change, but the number (in this case, address) that is stored in that fixed memory location can easily vary between various potential Foo
objects (or null
).
Beyond that, since C# is a managed language and not an unmanged language, it's not even true to say that the static variable will have a constant memory address. It's certainly possible, but it's really an implementation detail of the memory manager of C# that you shouldn't be relying on.
Upvotes: 1
Reputation: 34198
There is no deep copying of the object: the object itself is stored on the heap, not on the stack. You are correct that someStaticVariable
will always have the same address. Your misunderstanding, I believe, is in what's stored at that address.
When you declare a variable of a reference type (any object
type, such as Foo
in your code), the variable itself isn't the object: it's a variable that stores the address of your object. That address is just a number. So, "the address of someStaticVariable
" isn't the address of the Foo
itself; it's the address of the address of the Foo
.
In the same way, this is why your someStaticVar
doesn't "disappear." What happens in your code is that a Foo
is created at some address in memory, and localVariable
is set to a value that represents the address in memory of the Foo
. When you perform someStaticVar = localVariable
, what happens is that the address is copied from localVariable
to someStaticVar
, and thus both variables point at the same Foo
. When localVariable
disappears, someStaticVar
is not affected.
Upvotes: 1