dcsimg
Results 1 to 14 of 14

Thread: [RESOLVED] Heap vs Stack confusion

  1. #1

    Thread Starter
    Member
    Join Date
    Jul 2005
    Posts
    45

    Resolved [RESOLVED] Heap vs Stack confusion

    Hi,

    I always been under the impression that value types are stored on the stack while reference types are stored on the heap. Then the other day I read somewhere that said something in the line of "value types are stored on the stack unless they are part of a class in which case they are stored on the heap". What does that mean? I though everything is a class in .Net, even Modules are really compiled into some sort of static classes.

    So my question is simply this: When would a value type be stored on the heap?

  2. #2
    Cumbrian Milk's Avatar
    Join Date
    Jan 2007
    Location
    0xDEADBEEF
    Posts
    2,448

    Re: Heap vs Stack confusion

    As far as I understand...

    Value types only exist on the stack when they are instantiated within the body of a method. Properties are methods with a bit of extra syntactic sugar, so they count too.

    Only value types can exist on the stack. Reference types exist on the stack as a value type (GC handle) that we can't directly interact with.

    I don't think this is something to worry about.
    Last edited by Milk; Apr 4th, 2013 at 04:40 PM. Reason: linx
    W o t . S i g

  3. #3

    Thread Starter
    Member
    Join Date
    Jul 2005
    Posts
    45

    Re: Heap vs Stack confusion

    Hi Milk and thank you for your reply. I'm not worried I just wanted to understand it.

    What do you mean with "when they are instantiated within the body of a method"? Value types aren't instantiated, are they? Isn't an instance the same thing as a reference (and value types aren't reference types)?

    This also confuses me: "Only value types can exist on the stack. Reference types exist on the stack as a value type (GC handle) that we can't directly interact with", what does that mean? You first say that only value types can exist on the stack and then you tell me that reference types exist on the stack as a value type? I'm sorry but that just doesn't make any sense to me. I'm aware that value types exist on the stack and I was under the impression that they always did so, but then I read that a value type can exist on the heap and I was wondering when it does so?

  4. #4
    Cumbrian Milk's Avatar
    Join Date
    Jan 2007
    Location
    0xDEADBEEF
    Posts
    2,448

    Re: Heap vs Stack confusion

    I see my reply did not help.

    As far as I mean, you instantiate something when you create it. I should have perhaps wrote declared instead.

    I think of reference types as a special value type like a pointer only opaque and owned by the garbage collector.
    W o t . S i g

  5. #5
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    34,714

    Re: Heap vs Stack confusion

    Another way to look at it is this:

    A value type holds a value and a reference type holds a reference. That may seem simplistic, but consider what happens when you declare an Integer variable called Foo. For this variable, the compiler allocates sufficient memory to hold an integer (four bytes) and gives that chunk of memory the name Foo (not really, Foo is just an easy way for you to refer to the thing, the compiler only retains the name to make it easier for you, all the compiler really knows about is the memory the variable occupies). That chunk of memory IS the integer and it holds the integer. The chunk of memory could be memory on the stack, or it could be memory on the heap. It doesn't fundamentally matter where the memory is located, it matters that Foo is a chunk of memory that holds the actual Integer. In the case of a reference type such as all classes, if you were to create a variable called Bar of type SomeClass, then the compiler allocates sufficient memory to hold the reference to the class. Unlike the value type, Bar doesn't hold the actual class, it just holds a reference to the class. This is really convenient, because otherwise you wouldn't be able to pass classes to functions for complicated reasons that I'll skip for now. So, the value type holds the actual value, but a reference type only holds the reference to the actual value (which you have to explicitly create using something like New). So, where does the actual value of a reference type reside? It resides out there on the heap. The variable Bar, which only holds the reference to the actual variable, can be pushed onto the stack pretty easily, but pushing a whole class is probably impossible. At the very least, pushing a class would be quite difficult for complicated classes, as it may hold references to other objects, system resources, and all kinds of other things, which would mean that getting it off the stack when the stack frame goes away when the method returns might be a bit dicey.

    Not everything is a class, though. Everything can behave like a class, as you can cast even an Integer to type Object, but I see that as just a compiler trick to make all things work consistently. As long as you use an Integer as an Integer, it remains just a value and is not a class.
    My usual boring signature: Nothing

  6. #6
    PowerPoster techgnome's Avatar
    Join Date
    May 2002
    Posts
    32,729

    Re: Heap vs Stack confusion

    All value types are stored on the stack ... hence the "stack overflow" error generated if you call something recursively too far...
    References are stored on the heap.... pointers, classes, and so on... all on the heap...

    Not everything is a class... value types are not classes... they are primitive value types... even complex value types (structures) are value types, and reside on the stack.

    Ok... as for the statement: "value types are stored on the stack unless they are part of a class in which case they are stored on the heap"
    That's an inaccurate fallacy based on how it all works. Let's say you have a class with two properties: Name and Age. Name is a string and Age is an integer.
    When you create an instance of the class (Dim MySelf As New Person) ... a block of memory is carved out on the Heap - because we are dealing with a reference object, the class. The address of that location is then stored in your variable. Ah ha! We have a pointer. Ok... so now if we were to examine that memory location, what would we find? Not the name, nor the age... but rather Pointers TO that information .... over on the stack! That's because Name and Age are primitive value types... the heap can only store addresses... it doesn't actually store data. A reference isn't like a pointer... it IS a pointer...

    And of course things get even better and more convoluted when you start talking about passing value and reference variables ByRef and ByVal in subs & functions...

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

  7. #7

    Thread Starter
    Member
    Join Date
    Jul 2005
    Posts
    45

    Re: Heap vs Stack confusion

    Quote Originally Posted by Shaggy Hiker View Post
    A value type holds a value and a reference type holds a reference. That may seem simplistic, but consider what happens when you declare an Integer variable called Foo. For this variable, the compiler allocates sufficient memory to hold an integer (four bytes) and gives that chunk of memory the name Foo (not really, Foo is just an easy way for you to refer to the thing, the compiler only retains the name to make it easier for you, all the compiler really knows about is the memory the variable occupies).
    Thanks, but I did know all about that. I just wanted to know if the value of the integer (or some other value type) is ever stored on the heap or not and if it is then when is it stored on the heap instead of on the stack.

    Quote Originally Posted by Milk View Post
    As far as I mean, you instantiate something when you create it. I should have perhaps wrote declared instead.
    OK, so you didn't mean instantiate in the sense of creating a reference, however I'm still confused about your earlier reply.

    Quote Originally Posted by Shaggy Hiker View Post
    Not everything is a class, though. Everything can behave like a class, as you can cast even an Integer to type Object, but I see that as just a compiler trick to make all things work consistently. As long as you use an Integer as an Integer, it remains just a value and is not a class.
    OK. But when you create an integer, for example, and you run your code to do some calculations with it to produce a result then that code must be part of a class, right? Hence the integer is part of a class.

    Quote Originally Posted by techgnome View Post
    Not the name, nor the age... but rather Pointers TO that information .... over on the stack! That's because Name and Age are primitive value types... the heap can only store addresses... it doesn't actually store data.
    I'm sorry but that just sounds plain wrong. Now I'm even more confused than I was before.

  8. #8
    Super Moderator Joacim Andersson's Avatar
    Join Date
    Jan 1999
    Location
    Sweden
    Posts
    14,649

    Re: Heap vs Stack confusion

    Wow, I haven't seen this much confusion in a thread for a long time. Let me try to clarify this for you but let's make another thing fully clear: Is it important to know when something is stored on the heap vs on the stack? Well, maybe not. You can probably be a fine .Net programmer without knowing about the exact memory management that is done for you. That's actually kind of the idea when you have a garbage collector that cleans things up. However what you should know about is the life-span something has as opposed to knowing the memory location it occupies, and things on the stack has a different life-span over things that are located on the heap.

    Quote Originally Posted by shortblaze View Post
    I read somewhere that said something in the line of "value types are stored on the stack unless they are part of a class in which case they are stored on the heap". What does that mean?
    What this means, and what I think Milk tried to explain is that members of a class will be stored on the heap along with the rest of the object (not the class, but the instantiated object). So local variables (of value types) are always stored on the stack (that is not fully true since they can become part of closure which I explain further down but let's start with the assumption that this is true) so when the method (or property getter or setter) returns the value is popped from the stack and the memory is cleared (not really, it's marked as free. The program will actually not "clear" the memory). However if the value type is a field in the class, either a private or a public field it must be created as part of the object and is then stored on the heap.

    Code:
    Public Class Something
      Private _myFieldValueWhichIsStoredOnTheHeapAsPartOfTheObject As Integer = 5
    
      Public Sub DoSomething()
        Dim myLocalVariableOfValueTypeThatIsStoredOnTheStack As Integer = 3
        '[...]
      End Sub
    End Class
    So the value for the field (which in this case starts out as 5) in the code example above will be stored on the heap while the local variable (which is initialized with the value 3) is stored on the stack and will be popped just before the DoSomething method returns.

    A value can also be boxed (and a reference value can be unboxed) which is when a value is converted from a value type into a reference type. However the value type itself is not really moved to the heap when this happens instead an object is created on the heap and the value that is contained within the value type is copied to the heap.
    Code:
    Dim i As Integer = 3
    Dim o As Object = i
    Since "o" in the example above is an object it doesn't get a reference to the integer variable (which is stored on the stack) since that wouldn't be possible. Instead the value type is "boxed" and a copy of the value 3 (in this example) is stored with the object on the stack. That it doesn't reference the actual value type is easily seen here:
    Code:
    Dim i As Integer = 3
    Dim o As Object = i
    i = 5
    Console.WriteLine(o)
    The output of the above will be 3. The value in the object is not changed just because you changed the value in the integer so there is no reference to that value type stored in the object. So saying that a value type will be stored on the heap when the value is boxed is not technically correct. The value type stays in the memory space where it was initially created.

    I mentioned closures earlier. A closure is a lambda expression together with some data environment. Let's look at a simple example:
    Code:
      Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        Dim i As Integer = 0
        AddHandler Button1.Click, Sub()
                                    i += 1
                                    Button1.Text = "Clicked: " & i & " times."
                                  End Sub
      End Sub
    The integer variable in this code is obviously a local variable and should then be stored on the stack. However we then have a lambda expression (in this case as an event handler) which uses that variable. How is this possible, if the value is stored on the stack surely that variable is removed from memory as soon as the Form.Load event exists but still the value is changed whenever we click on the button. Well, this time the compiler will create a closure for us. The value type will not be stored on the stack at all, it will be moved to a field, which we by now know is stored on the heap so that the code in the lambda can be executed when at some point later the user decides to click on the button the value can be changed. This is really just a compiler trick, the compiler will rewrite the code for us so it will be equal to something like this:
    Code:
    Private i As Integer = 0
    
    Private Sub SomeArbitraryNameThatWillHandleTheClickEvent()
      i+=1
      Button1.Text = "..."
    End Sub
    
    Private Sub Form1_Load(sender As Object, e As EventArgs) Handles MyBase.Load
      AddHandler Button1.Click, AddressOf SomeArbitraryNameThatWillHandleTheClickEvent
    End Sub
    Of course the above is somewhat simplified, the compiler creates some other name for the field and also adds other stuff but in essence this would be the result. So in this case the local variable will also be stored on the heap (since it's only local during design time and it will be moved to a field variable during compile time).

    Quote Originally Posted by techgnome View Post
    Not the name, nor the age... but rather Pointers TO that information .... over on the stack! That's because Name and Age are primitive value types... the heap can only store addresses... it doesn't actually store data.
    This is completely wrong. The heap can hold data and you will never store references to the stack on the heap. Doing so would be dangerous in deed since the stack memory is in a constant flux and change all the time during run-time. What if you have a reference on the heap that points to a memory location on the stack that has been released? That memory location is technically not part of the program anymore. What would then happen when you try to use that reference?
    Last edited by Joacim Andersson; Apr 5th, 2013 at 12:52 AM.
    Joacim Andersson
    If anyone's answer has helped you, please show your appreciation by rating that answer.
    I'd rather run ScriptBrix...
    Joacim's view on stuff.

    MVP

  9. #9
    PowerPoster Evil_Giraffe's Avatar
    Join Date
    Aug 2002
    Location
    Suffolk, UK
    Posts
    2,555

    Re: Heap vs Stack confusion

    Just to further add to Joacim's point. The JIT compiler can additionally choose to enregister a variable. This means it stays in the registers and never hits main memory at all. Clearly these local variables are neither on the stack nor the the heap!

    But the main point is this: This is all irrelevant to the programmer. The .NET runtime spec does not define any such thing as a stack or a heap. That the current Microsoft desktop implementations use it is an implementation detail thanks to Windows providing a per-process (or is it per-thread? can't remember) 1 megabyte "stack" (I don't think it's necessary to use it as a stack, I recall hearing that it's just an array that is called a stack and is generally used as a stack). It's efficient to release memory from the stack as you just unwind it, but you have to release from the most recently allocated things first. With local variables, it is easy to see that when you exit a function you can release all of that memory, so it all works nicely. It is possible for the analyser to do more work and figure out if any objects live beyond the local function - if that work was done, those objects could live quite happily on the stack as well, but it isn't done, so they can't.

    What's important is the semantics and observable characteristics of value types and reference types guaranteed by the spec. All runtimes will guarantee those (assuming they conform to the spec), but there is no guarantee that they will provide a stack and a heap as part of their implementation.

  10. #10

    Thread Starter
    Member
    Join Date
    Jul 2005
    Posts
    45

    Re: Heap vs Stack confusion

    Thank you Joacim, I think I finally understand what the book I was reading was trying to say. Very nice explanation about the closures as well. It seems that in almost all the threads I've created you sooner or later comes in and give me the explanation in a simple understandable way.

    @Evil_Giraffe, thank you for the additional input. I was however already aware that the compiler could do some optimization with regards to the CPU registers.

    I also want to thank all you others for your input.

  11. #11
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    34,714

    Re: Heap vs Stack confusion

    Quote Originally Posted by Evil_Giraffe View Post
    Just to further add to Joacim's point. The JIT compiler can additionally choose to enregister a variable. This means it stays in the registers and never hits main memory at all. Clearly these local variables are neither on the stack nor the the heap!
    I wrote that....then deleted it. Technically, if you got low enough level, YOU could write variables like that, too, but I felt that would just muddy the waters. A fun point, though.
    My usual boring signature: Nothing

  12. #12
    PowerPoster Evil_Giraffe's Avatar
    Join Date
    Aug 2002
    Location
    Suffolk, UK
    Posts
    2,555

    Re: [RESOLVED] Heap vs Stack confusion

    I'm not sure how you could get that behaviour - it's the JIT compiler, so it's decided when the IL is compiled into machine code, so even IL rewriting shouldn't be able to force this, as far as I understand it?

    But it's worth pointing out to counter the incorrect "value types always go on the stack" just as much as the other facts, IMO. If you're getting into the details of how a specific implementation actually does its memory management, then you really should consider (or at least mention in passing) as much of it as possible. Another thing that's not been mentioned is Iterator functions. In C# locals within an iterator block can get hoisted to a hidden class in the same way as for closures - presumably now VB has them something similar happens for those as well.

  13. #13
    Super Moderator Shaggy Hiker's Avatar
    Join Date
    Aug 2002
    Location
    Idaho
    Posts
    34,714

    Re: [RESOLVED] Heap vs Stack confusion

    I didn't mean in .NET, I meant in ASM. That's why I deleted it, because it was too much of a digression. I felt the original question was odd enough, since stack vs heap matters so little in practical terms, that the OP might want to wander in the weeds a bit, but that seemed too far, since it left the language itself.
    My usual boring signature: Nothing

  14. #14
    PowerPoster techgnome's Avatar
    Join Date
    May 2002
    Posts
    32,729

    Re: [RESOLVED] Heap vs Stack confusion

    well regarding my statements... mea culpa... it's possible I've misunderstood something all this time... getting into the weeds that deep isn't usually something I have to contend with... But after I thought about it, you're right... that doesn't make a whole lot of sense...

    note to self - don't reply to deep weed threads before 3 cups of coffee...

    -tg
    * I don't respond to private (PM) requests for help. It's not conducive to the general learning of others.*
    * I also don't respond to friend requests. Save a few bits and don't bother. I'll just end up rejecting anyways.*
    * How to get EFFECTIVE help: The Hitchhiker's Guide to Getting Help at VBF - Removing eels from your hovercraft *
    * How to Use Parameters * Create Disconnected ADO Recordset Clones * Set your VB6 ActiveX Compatibility * Get rid of those pesky VB Line Numbers * I swear I saved my data, where'd it run off to??? *

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  



Featured


Click Here to Expand Forum to Full Width