What is the advantage of using Java Stack Variables?

Stack Variables

Stack Variables
In this article we will talk about the different ways to declare variables in Java and the advantage and disadvantage of using local variables or Stack variables. In java, there are differences between stack variable and other types of variables like local and class. This article will describe the details with example and help you to implement it correctly.

Introduction:
The JVM divides the memory into following sections:

  • Heap: This section contains objects and also the reference variables.
  • Stack: This section contains methods, local variables and reference variables.
  • Code: This section contains the byte code.
  • Static: This section contains the static variables and methods.

In Java, we can declare variables in the following three manners:

  • Instance variables.
  • Class level or Static variables.
  • Local or Stack variables.

Instance variables: Instance variables indicate that they exist per instance of the class. If a class has ten instances, we will have ten copies of each instance variables. Instance variables are also termed as non static variables.

Class level or Static Variables: Class level or Static variables exist per class no matter how many instance of the class we create. These are declared using the static keyword. Static variables are initialized when the class is first loaded in the JVM.

Local or Stack Variables:  Local or stack variables are defined within a method and are local in scope. Their scope varies depending upon the access modifier used to declare them.

Java memory distribution

Java memory distribution

Pic1: Java memory distribution

Let us see the following three java codes

Listing 1: Access to a stack variable:

[Code]

package com.home.variables;

public class StackVariables {

// Access to Stack variables

public void stackAccess(int maxVal) {

int j = 0;

for (int i = 0; i < val; i++) {

j += 1;

}

}

}

[/Code]

Listing 2: Access to an instance variable

[Code]

package com.home.variables;

public class InstanceVariables {

private int instVar;

//Access to Class instance variable

public void instanceAccess(int val) {

for (int i = 0; i < val; i++) {

instVar += 1;

}

}

}

[/Code]

Listing 3: Access to a static variable

[Code]

package com.home.variables;

public class StaticVariables {

private static int staticVar;

//Class static variable access

public void staticAccess(int val) {

for (int i = 0; i < val; i++) {

staticVar += 1;

}

}

}

[/Code]

Each of the above java classes executes a loop for equal number of iterations. The only place where they differ is the type of variable which gets incremented within the for loop. In listing 1, a local stack variable is used and incremented by 1 every time the loop executes. Listing 2 shows an example of using and incrementing a class level or an instance level variable. Listing 3 is an example of using an incrementing a static variable.

Instance level variables and static variables take almost same amount of time to execute. Whereas local or stack variables are two to three times faster. In case of local or stack variables, since the JVM has to perform less task than when accessing static or class level  or instance level variables. The following generated byte code makes it clear:

Listing 4: Byte code generated against Listing 1 (Stack Access)

[Code]

Method void stackAccess(int)

0 iconst_0         //Push 0 onto the stack.

1 istore_2         //Pop 0 and store it at index 2 of the local variable table(j).

2 iconst_0         //Push 0.

3 istore_3         //Pop 0 and store it at index 3 of the local variable table(i).

4 goto 13          //Jump to location 13.

7 iinc 2 1         //Increment j stored at index 2 by 1.

10 iinc 3 1         //Increment i stored at index 3 by 1.

13 iload_3          //Push the value at index 3(i).

14 iload_1          //Push the value at index 1(val).

15 if_icmplt 7      //Pop i and val. Jump to location 7 if i is less than val.

18 return           //Return to calling method.

[/Code]

Listing 5: Byte code generated against Listing 2 (Instance or Class level Access)

[Code]

Method void instanceAccess(int)

0 iconst_0         //Push 0 onto the stack.

1 istore_2         //Pop 0 and store it at index 2 of the local variable table(i).

2 goto 18          //Jump to location 18.

5 aload_0          //Push index 0(this).

6 dup              //Duplicate the top stack value and push it.

7 getfield #19 <Field int instVar>

//Pop the object reference for this and push the value for instVar.

10 iconst_1         //Push 1.

11 iadd             //Pop the top two values, push their sum.

12 putfield #19 <Field int instVar>

//Pop the top two values and store the sum in instVar.

15 iinc 2 1         //Increment i stored at index 2 by 1.

18 iload_2          //Push the value at index 2(i).

19 iload_1          //Push the value at index 1(val).

20 if_icmplt 5      //Pop i and val. Jump to location 5 if i is less than val.

23 return           //Return to calling method.

[/Code]

Listing 6: Byte code generated against Listing 6 (Static Access)

[Code]

Method void staticAccess(int)

0 iconst_0         //Push 0 onto the stack.

1 istore_2         //Pop 0 and store it at index 2 of the local variable table(i).

2 goto 16          //Jump to location 16.

5 getstatic #25 <Field int staticVar>

//Push the value from the constant pool for staticVar.

8 iconst_1         //Push 1.

9 iadd             //Pop the top two values, push their sum.

10 putstatic #25 <Field int staticVar>

//Pop the value for sum and store it in staticVar.

13 iinc 2 1         //Increment i stored at index 2 by 1.

16 iload_2          //Push the value at index 2(i).

17 iload_1          //Push the value at index 1(val).

18 if_icmplt 5      //Pop i and val. Jump to location 5 if i is less than val.

21 return           //Return to calling method.

[/Code]

The above generated byte code for the three approaches gives a clear picture that using Stack level variables or local variables is an efficient way to use variables in Java. JVM is stack based and is therefore more optimized to use stack level data. The local variables are stored in a local variable table on the Java operand stack and are accessible very easily and efficiently. It becomes a costly affair to use and manipulate a static or an instance level variable as the JVM has to use an expensive opcode in order to access these variables from the constant pool.

The code given in listing 2 and listing 3 can be restructured in the following way to perform the task in an efficient way.

Listing 7: Restructured way to access an instance variable

[Code]

package com.home.variables;

public class InstanceVariables {

private int instVar;

//Access to Class instance variable

public void instanceAccess(int val) {

int j = instVar;

for (int i = 0; i < val; i++) {

j += 1;

}

instVar = j;

}

}

[/Code]

Listing 8: Restructured way to access a static variable

[Code]

package com.home.variables;

public class InstanceVariables {

private int staticVar;

//Access to Class instance variable

public void instanceAccess(int val) {

int j = staticVar;

for (int i = 0; i < val; i++) {

j += 1;

}

staticVar = j;

}

}

[/Code]

As we see the methods instanceAccess and staticAccess are modified to copy their instance or static variables into a local stack variable. The operation or the manipulation is performed on the copied local stack variable and when the manipulation of a variable is over, the value is copied back to the instance or static variable. This simple change significantly improves the performance of instanceAccess and staticAccess. With this change the execution time of all these three methods are now effectively same.

This approach does not advocates the fact that we should avoid using static or instance variables. Rather we should use whatever mechanism makes sense and is more efficient for our design. e.g. in the above example, if we need to access a access a static or an instance variable in a loop, we can significantly improve the performance of the code by temporarily storing them in a local stack variable. This provides a more efficient sequence of byte code instructions for the JVM to execute.

Summary: To conclude the discussion, we have summarized the points below. We need to understand the concept of java variables and their scope. And the most important part is the implementation of these variables in correct place. Hope this article will help you to understand the details and use it in your application.

  • JVM divides the memory into following sections :Heap, Stack, Code and Static
  • Java allows us to declare variables in the following three ways:
    • Instance
    • Static
    • Local or stack.
  • Using Stack level variables accelerates the execution of a program by two to three times.
  • If have to use a static or an instance level variable, we should copy it to a local variable before manipulating the data or doing some operation.

 

 

 

 

 

Tagged on: ,
============================================= ============================================== Buy best TechAlpine Books on Amazon
============================================== ---------------------------------------------------------------- electrician ct chestnutelectric
error

Enjoy this blog? Please spread the word :)

Follow by Email
LinkedIn
LinkedIn
Share