.NET Stack and Heap

Video Statistics and Information

Video
Captions Word Cloud
Reddit Comments
Captions
hi I'm Wallace Kelly and I'm a student recently asked me some questions related to the stack related to heap related to reference variables and the use of the new operator and how that all works together so I'm going to address some of those issues now the important things to take away from this talk are that local variables are allocated on the stack class instances are allocated on the heap and the reference variables and those instances they're really distinct from each other I'm going to show you some examples and draw you some pictures to really drive these three points home so as I mentioned memory can be is separated into two areas there's a portion of the memory called the stack and that's where local variables are allocated and then there's a portion of the memory called the heap and that's where instances of classes are allocated all throughout this talk I'll be using this class person it's a simple class with a simple string name and an integer age so if we were to declare a variable of type person as you see here in the C sharp code person P this doesn't mean allocate enough space for a name and allocate enough space for a age all it means is allocate enough space for a reference to a person so person Pete merely declares a variable that variable is allocated the space to store that variable is allocated on the stack and initially it's undefined it has no value it's just random bits so if we were to write code that said P dot name equal Wally like shown here it wouldn't compile the compiler would say use of an unassigned local variable because it had detected that we hadn't set P equal to anything we could get this to compile by saying P equals null and in that case we're zeroing out this reference we're saying that this reference doesn't point to anything this variable P it doesn't point to a person but I'm going to null it out so this would compile but at runtime when I try to set P dot name the runtime will detect that the object reference is not set to an instance of an object and it'll throw a null reference exception now let's compare this use of variables of type person with actually allocating a person we allocate all the space needed for the data members of a person by calling the new operator so here you can see I called new person and on the heat I get enough space for a reference to a name and enough space for an age now instances of classes the member variables are a little bit different in that those are initialized so here you can see that name is actually set to null an age is set to zero which are the default values for reference types and integers of course this program doesn't do anything useful yet and so what we have to do is somehow store away a reference to this person out on the heap if we want to do anything with it so in my code I could say person P and I could say new person and these would be completely distinct from each other my variable P isn't pointing at person yet and in fact it's not initialized but of course what I would most likely do is say P is equal to new person and so now my code has a variable pointing to this memory space that has all the data associated with each person more often than not will simply write the code like this on a single line of code person P equals new person and this can be somewhat deceptive if we don't understand that the variables and the objects they point to are really distinct from each other now once I've allocated this new person and I have a variable pointing to it I can access the members on that person with the dot operator so P dot name means go to the person that P is pointing to go to the name field and set it to Wally now I should point out that name here is a string and string is also a reference type so you'll recall it as I backup that name was equal to null then when I say P dot name equals Wally what really is going on is that a new string is allocated or rather and pointing name at my string that has Wally and in fact string is an object that contains an array of characters and so that point to another character but I'm not going to draw that every time but I just want to point out that yes name itself is a string and so that points to other objects on the heap here I now set P dot age equal to 40 go to the vet go to the person that the variable P is pointing to go to the H field and set that to 40 all right well let's continue on and now what I'm going to do is modify my person class so it contains a constructor so I have a constructor here that takes in the initial values for name and age and set those and that's for convenience so that now on a single line of code I can say person P there's my variable allocate a new person and here are the name in the age fields because that's how I define my constructor what if after allocating that person assigning its location to the variable P and then what happens if I set P equals to null well the answer is is that I lose that reference these are all null doubt the variable P is milled out and I lose that connection that was between my variable and the object and so now nothing is pointing that person sometime in the future the garbage collector is going to run and this memory that was allocated for person will be freed up and made available for other instances of objects all right let's look at some other examples here person P equals new person now I had allocated a second person so I do the new person allocating another person out here on the heap and if I didn't assign that variable if I didn't assign what's returned by the new operator to some variable I would never be able to access that person again but what if I said now P my variable P is pointing at this new person well now this variable P is pointing to this instance of person the second one and I've lost my reference to the first one and once again the garbage collector will come and free that space up and later alright let's look at some more examples let's suppose I allocate a second person but this time I store away a reference to that second person so now on the stack I have two variables person 1 and person 2 and both pointing at different instances of person no surprises there now let's step back and set our person class aside for a moment and think about some value types persons a class it's a reference type so it works just as I described there are some what you might think of as native types or primitive types or in what we call net what we call value types and integer is an example of that value type and so in this case what happens when I define a declare a variable of type integer called age well local variables go on the stack so space is reserved on the stack to store an integer and unless I said it is just garbage bits it's undefined if I set it to something then that value gets written right there into the stack for that integer now let's suppose that I create a new person person P equals new person and I have person name I've set it equal to Wally and now I want to set the age and the question is what happens down here in the code if I say PA equal age well because age because integer is a value type what happens is that value that's in the age variable that value 42 gets copied out here on to the heap and now the person dot age has that value of 42 that value is copied so after executing it there is no connection any longer even though we say pH equals age there's no connection any longer between the variable the local variable lowercase age the integer and the field of person age because that's a value type that value is simply copied over in fact if I change age equal to 73 my lower case age that has no impact on my person alright so now let's look at reference types that contain reference types so we have class person name and age but now this also has another field of type person that points to a spouse and so whenever I allocates class person enough space is reserved not for a whole nother person but simply for a reference to a person you can think of it as a pointer so here in our class in our simple static void main person p1 equals new person person p2 equals new person we have those two persons out there now what if I want to set spouse so I want spouse here which is currently no I want this to point to the second person so in my code I would say p1 spouse equals p2 and what that would do is it would say go to the object that p1 is pointing to go to the spouse field and set that not to null but set it to whatever p2 has well p2 has this reference 2 3 4 5 6 7 right so what would happen is the first person got spouse would have 1 2 oops have a little bit of a mistake there so let's see is that right yep that's a little bit of a mistake so let's correct that so this should be 2 3 4 5 6 7 glad I caught that yeah so person 1 the person that person 1 is pointing to the spouse field is now pointing at the person that person 2 is pointing to now let's think about how these references work when you're passing them to methods so here we have a method called celebrate birthday and it takes in a reference to a person we're going to call that method celebrate birthday with a person P equals new person so here when we're at this line of code person V equals in person we have this familiar diagram with the stack in the heat then winds were about to call in to celebrate birthday space is allocated on the stack for the local variables in that method and that includes the variable person that gets passed in so we have space on the stack for the variable person and because we celebrate birthday passing in the variable P the value that P has in it the reference of P is get set through the reference person so now both the variable P and the variable person are pointing to the same instance out on the heap then as we advance through celebrate birthday you can see that the code says go to person age and increment the age by one so that incremented the age from 40 to 41 then when this returns person the person variable the lowercase person variable goes out of scope and because it's on the stack it can be conveniently de-allocated by simply moving a stack pointer down and so it is doesn't have to be garbage collected it merely goes out of scope but this object out on the heap we still have a variable pointing at it the lowercase variable P let's do that similar lady let's call a method that creates an object on the heap and then returns a reference so here I have a method create person and what it does is it allocates a person on a heap and then returns it so as we go into main space is allocated on the stack for the variable P it's initially uninitialized and then as we execute create person space is allocated for our lower case person variable we create a new instance of person lower case person points to that new instance and then we returned the value of that reference so when this returns a value one two three four five six will be copied into our local variable P and because the variable person was in the on the stack for the create person method it can be conveniently de-allocated and then our method can continue and now person this lower case P has a reference to the person that was allocated in this other method all right so let's review what we've covered we've seen that local variables are allocated on the stack class instances are allocated on the heap and reference variables and instances it's helpful to keep in your mind that those are really distinct from each other to help you understand how those works how those work I hope that's been helpful I'll see you next time
Info
Channel: Wallace Kelly
Views: 86,765
Rating: 4.9690986 out of 5
Keywords: .NET, C#, Visual Studio
Id: clOUdVDDzIM
Channel Id: undefined
Length: 13min 6sec (786 seconds)
Published: Tue Jun 26 2012
Related Videos
Note
Please note that this website is currently a work in progress! Lots of interesting data and statistics to come.