9

I do know that in Java, (perhaps in .net too) , primitives are stored on stacks , where as reference types are stored on heaps.

My question was that I do not understand the proc/cons for this behavior. Why can't we reference a memory location inside our stacks instead? . I couldn't find a proper explanation as I googled ( maybe I suck at it) , but if you people can provide some insights I would be grateful

Thanks.

trincot
  • 317,000
  • 35
  • 244
  • 286
Muhammad Ahmed AbuTalib
  • 4,080
  • 4
  • 36
  • 59

4 Answers4

10

I do know that in Java, (perhaps in .net too) , primitives are stored on stacks , where as reference types are stored on heaps.

No. It does not depend on whether its a primitive or a reference. It depends on the scope whether the stack or the heap is used. Local variables are allocated on the stack, member variables are allocated on the heap when the object is instantiated.

See also Do Java primitives go on the Stack or the Heap?

My question was that I do not understand the proc/cons for this behavior.

Data stored on the stack only lives as long as your method is executing. Once the method is done, all data allocated on the stack is removed. Data stored on the heap lives as long as it is not discarded (which, in case of Java, is done in the background by the garbage collector). In other languages as C/C++, you explicitly need to delete/free data which was allocated on the heap.

Consider the following code snippet:

String someMethod() {
  int i = 0;
  String result = "Hello";

  i = i + 5;
  return result;
}

Here, a primitive (int i) is created on the stack and some calculation is done on it. Once the method finishes, i cannot be accessed anymore, and its value is lost. The same is basically true for the result reference: the reference is allocated on the stack, but the Object (a String object in this case) is allocated on the Heap. By returning the reference as return value, the object it references can still be used outside the method.

Community
  • 1
  • 1
Andreas Fester
  • 36,091
  • 7
  • 95
  • 123
  • I was going along fine with your explanation , until you said . the reference is allocated on the stack, but the Object (a String object in this case) is allocated on the Heap I understand that as the method starts , integer "i" would have 2 bytes (depending on platform) , and would go away once the method completes. However you say that the "result" would also be allocated memory on the stack , as well as in the heap ? Or do you imply that only a pointer to a memory location in the heap would exist during the method execution . – Muhammad Ahmed AbuTalib Dec 17 '12 at 12:03
  • 3
    @MuhammadAhmedAbuTalib Exactly - simply said, a reference is a pointer to the object and this pointer is allocated on the stack, while the object itself is allocated on the heap. The object itself can contain other primitives and other references as members, in which case they would be allocated on the heap when the object is instantiated. – Andreas Fester Dec 17 '12 at 12:11
7

You can't generally store reference types on stack because the stack frame is destroyed upon method return. If you saved a reference to an object so it can be dereferenced after the method completes, you'd be dereferencing a non-existent stack location.

The HotSpot JVM can perform escape analysis and, if it determines that an object cannot possibly escape the method scope, it will in fact allocate it on the stack.

Marko Topolnik
  • 195,646
  • 29
  • 319
  • 436
  • so do you imply that the decision of storing a piece of data either in stack or heap , has nothing to do with the fact that it is a primitive or a reference type ? Rather this relates to the fact that whether it is global or local? . If this is true then my whole life was a lie , I thought that no matter what if I do Abc obj = new Abc() , the space for Abc would always go into the heap . – Muhammad Ahmed AbuTalib Dec 17 '12 at 12:13
  • If it is primitive, then it is **definitely on stack**, so your "nothing to do" is wrong. But yes, the JVM has the final verdict on where the object resides because this strictly an implementation detail. That is why I don't see a reason why someone would spend time worrying about it. – Marko Topolnik Dec 17 '12 at 12:16
  • 3
    You need to distinguish between the space for `Abc` and the space for the reference (kind of pointer) to `Abc`. In `Abc obj = new Abc()`, memory is allocated on the heap to store the `Abc` object, and (assumed the code line as written is part of a method body) space for the `obj` **reference** is allocated on the stack. – Andreas Fester Dec 17 '12 at 12:16
  • one last question Marko , you are correct I should not worry about these details but curiosity kills. If supposedly Abc is in a method body , such that it is of local nature and is not referenced anywhere else in the entire program In such a situation , according to your earlier comment , would the space for reference , and space for Abc , both be in stack ? – Muhammad Ahmed AbuTalib Dec 17 '12 at 12:29
  • Yes, that is correct, but note that there are more prerequisites, like never passing the reference to other methods, since the static code analyzer in the JIT compiler can't be sure what that method could do, especially in the face of dynamic dispatch. Google for "HotSpot escape analysis" to dig into the fine details. – Marko Topolnik Dec 17 '12 at 12:32
2

where as reference types are stored on heaps.

I don't know what exactly you mean by that part, but remember that, only objects are stored on heap, whereas, references pointing to those objects are still on the stack. Probably this was the doubt you had.

Now, you should also note that, only local variables are stored on stack, whereas instance / member variables are stored on Heap.

For e.g.: -

String str = new String("Rohit");  // Local variable

In above case, str reference will be allocated memory on stack, if of course it is defined in some local scope. And it will point to a new string object created on Heap.

Rohit Jain
  • 209,639
  • 45
  • 409
  • 525
  • Thanks for the answer , it is simple and yet descriptive. However please also note I wanted to know "why" . Can you please shed some light as to WHY the heap , why can't we just use the stack . Is it because stack is the main "working area" and it changes it's state as the code executes hence cannot be considered as a placeholder for globals? . – Muhammad Ahmed AbuTalib Dec 17 '12 at 12:08
  • and yes my reference types you correctly inferred what I meant , you have cleared the confusions I had for sure . But just this one bit remains – Muhammad Ahmed AbuTalib Dec 17 '12 at 12:10
  • 1
    Every method invocation is stored on Stack. Along with that are stored all the parameters that we pass to it, and the local variables that are created. Now, the stack storing those parameters and local variables are deallocated, as soon as the execution goes out of the method. And their scope ends. And hence there is a better memory management. Now, if we talk about objects, remember one thing that, objects created in one scope can be used in any other scope, if it holds a reference to that object. So, they should not be stored on Stack. – Rohit Jain Dec 17 '12 at 12:14
  • Let's understand this way. When you call a method from another method. The references you pass are copied into the stack created for that method. And it points to the same object, as the original reference was pointing to. So, now, you have two references on two stacks pointing to same object on Heap. Do ask if you need more clear explanation. – Rohit Jain Dec 17 '12 at 12:17
  • So, one benefit of storing `objects` on heap, is that you can access them from outside the scope where it was created. – Rohit Jain Dec 17 '12 at 12:21
  • Thank you for your answers, rohit jain . They have helped me in a clear insight . Also to add I have a very good friend by your same name in banglore . :) – Muhammad Ahmed AbuTalib Dec 17 '12 at 12:54
0

Why can't we reference a memory location inside our stacks instead?

You can but think of this decision as Memory Architecture decision.

By concept, ideally, any data can't be retrieved from stack if it is not on top of it. But in real world you require some location to be accessed from anywhere in the program. So, it can't be stack. and they named it heap.

This link may throw more light on it.

Azodious
  • 13,752
  • 1
  • 36
  • 71