简体   繁体   中英

How stack memory is accessed in Java

I am trying to understand Java stack and heap memory. On reading from different sources, I came to below conclusions:

  1. Locally (part of a method) declared primitive types like int, bytes, char, etc are stored on the stack.

  2. While static and instance (part of an object instance or class) primitive types are stored on the heap.

  3. in short, Local variables are stored on the stack, while instance and static variables are on the heap.

  4. The local referenced object will be created in heap but, the variable will be created in the stack.

  5. The instance/ static referenced object will have both variable and object created in heap.

( For instance,a local car ferrari = new car() , will create a memory for ferrari in the stack and the actual object will be in the heap.

The stack variable ferrari will have the reference address to heap location of the actual object).

But on further reading, I read that in the stack the memory is allocated to the top of the previous frame. Which made me confused about below scenarios:

Question 1:

let my method be:

calculate(){
int a=15;
int b=25;

return a+b;
}

But according to stack, last-in will be b. So the value of a will out of scope until the value of b is used from the stack.

How is the program able to use the value of 'a' before 'b' ? for the operation a+b.

Question 2:

let my method be:

calculate(){
int a=15;
int b=25;
int z= a+b;
int y=a+b;

return y;

}

Now I have used both variables a and b for calculating 'z', how is variable y is able to access a and b again as it is already used from the stack.

I am not an expert in Java, thank you so much if someone could explain in simple words.

Every thread has its own stack .

Whenever a thread invoke a method, a new block is created in the stack memory for that method to hold local primitive values and reference to other objects in the method. This memory block is called stack frame . As soon as method ends, the block becomes unused and it is removed from top of the stack. This is because stack memory is always referenced in LIFO (Last-In-First-Out) order.

So, if you have code:

void go(){
   int x = 1;
   foo(x);
}

void foo(int y){
   int z = y;
   bar();
}

void bar(){
   Hello h = new Hello();
}

Stack would look something like this:

在此处输入图片说明

On this picture only h is in scope. But after bar() method is done, both variables, y and z , will be in scope.

Internally, stack contains local variables array and operand stack .

In local variables array are stored parameters of the method and all local variables for that stack frame. Also, if stack frame represent instance method then on position 0 of local variable array will be this reference that points to the object on the heap. If method is static than on the position 0 will be first argument of the method. The size of the array of local variables is determined at compile time. To see local variable array you need to look inside compiled Java code. For your first calculate() method (in case it is static ), local variables array will look like:

在此处输入图片说明

You can see relation between variable name ( Name column) and its position in array ( Slot column).

Operand stack is the stack used for operations on variables from local variables array. On operand stack are variables from local variable array put and, in your example, added and assigned to other variables that are again saved in local variable array.

Question 1 : How is the program able to use the value of a before b for the operation a + b ?

Because there is pop operation that read and then remove value from stack. To add these two values, you pop (read and remove) last value from operand stack (value b ). Now is value a at the top of operand stack. Pop (read and remove) this value also (operand stack is now empty) and add these two values. Put result back on operand stack. Operand stack now contains only result.

Detail explanation:
When you call calculate() new stack frame is created and put on the top of stack. Statement int a = 15; is internally divided in 2 steps:

  1. constant 15 is put on top of operand stack,
  2. pop (read and remove) the value from operand stack (this is constant 15 ) and save it in local variables array at specific index.

Same steps are repeated for int b = 25; . Now you have 2 values saved in local variables array and empty operand stack. Last part return a + b; is done with 4 steps:

  1. push (load) value a from local variable array to operand stack,
  2. push (load) value b from local variable array to operand stack. Now you have two values on operand stack.
  3. pop (read and remove) first value from operand stack (this is b value). Pop second value from operand stack (this is a value). In this moment operand stack is empty. Add these two values and push result back on operand stack. Now operand stack only contains result of add operation.
  4. pop value from operand stack and return it to whoever called this method. Now is operand stack empty.

In this moment, because method is done, stack frame is removed from stack.

Question 2 : Now I have used both variables a and b for calculating z , how is variable y able to access a and b again as it is already used from the stack?

Because there is local variable array inside stack frame which store all local variables defined in that stack frame.

Detailed explanation:
int a = 15 and int b = 25 are done in same way as in Q1. int z = a + b; is performed like this:

  1. push (load) value a from local variable array to operand stack,
  2. push (load) value b from local variable array to operand stack. Now you have two values on operand stack.
  3. pop (read and remove) first value from operand stack (this is b value). Pop second value from operand stack (this is a value). In this moment operand stack is empty. Add these two values and put result on operand stack. Now operand stack only contains result of add operation.
  4. pop (read and remove) the value from operand stack ( a + b result) and save it in local variables array at specific index.

int y = a + b; is performed in same way as int z = a + b; .

Last part return y :

  1. push y value from local variable array to operand stack,
  2. pop value from operand stack and return it to whoever called this method. Operand stack is now empty.

Because method is done, stack frame is removed from stack.

Pay attention that there is stack, that is contained from multiple stack frames, but also that inside every stack frame you have operand stack that is used for operation inside that stack frame.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM