Memory Management in Java

174
heap_stack_cover.
Advertisement

You are a Java Developer.You does not need to bother about memory management in Java because Java has automatic memory management system and a quiet nice Garbage Collector also works in background for removing the unused and non – referenced variable from the memory and free up the space.

                     Generally , Memory is divided in two parts; Stack and Heap.Heap memory is larger in size whereas Stack memory is limited in size, but it is reverse in case of performance, Stack memory is more efficient when compared with Heap.


Heap Memory Space:

Heap Space is used by JVM (Java Virtual Machine) to allocate memory to objects at run-time. Hence Heap memory is only used for storage purpose.

                     Heap memory is created at the time of JVM startup and is limited to one(1) means we cannot create more than one Heap Memory Space for Same JVM or for Single Program Execution.

Objects and their instance variables are available globally so data stored in Heap Memory Space is Not Thread Safe because more than one thread can access the data at a time.

Garbage Collector works to free up memory by clearing Objects that had no reference to other.By using Garbage Collector, Heap Memory Space can automatically free up and used for another Objects.

Array in Java also stored in Heap Memory because Array is an Object in Java not only memory Space.

Heap memory is larger in size compared to Stack memory,When Heap Memory Space is full then it throws java.lang.OutOfMemoryErrorOutOfMemoryError hardly happens.

Below program describes you when and how OutOfMemoryError occurs:

public class Heap_OutOfMemoryError {
    public static void main(String[] args) {

        double mb = 1024*1024;
        Long maxMemory = Runtime.getRuntime().maxMemory();
        System.out.println(maxMemory/mb+" MB");
        int[] matrix = new int[(int) (maxMemory + 1)];

        for(int i = 0; i < matrix.length; ++i)
        matrix[i] = i+1;
    }
}

In this program first we get the max memory for the Heap and then after calculating heap memory we had created Integer type array and giving the size of array one more than the Heap Memory Space as before i said that arrays are objects  in java and the memory for arrays are stored in Heap.

1512 MB
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
  at Heap_OutOfMemoryError.main(Heap_OutOfMemoryError.java:7)

Stack Memory:

Stack Memory is used for execution purpose in java.Architecture of Stack is in form of LIFO(Last-In-First-Out) means who comes in stack first leaves the stack memory in last.

              Stack memory is separate  for each and every thread and created every time when different thread comes for execution so Stack memory accessed by single thread at a time and also Stack memory is thread-Safe.

Stack memory also contains the reference of objects stored in Heap Memory.Stack memory only contains short time lived local primitive variables and reference of Objects from Heap.

Stack has limited memory compared to Heap and if method call is more recursive then sometimes it throws java.lang.StackOverFlowErrorIt grows and shrinks as the new method comes in stack but after reaching max size it throws StackOverFlow error.

Program to show the Stack Overflow Error occurs in Java:

 

public class Show_StackOverFlowError {
   public static void main(String[] args) {

      methodOne();
   }

   public static void methodOne(){
     System.out.println("Method One");
     methodTwo();
   }

   public static void methodTwo(){

     System.out.println("Method Two");
     methodOne();
   }
}

In this program main()method called the methodOne()and inside the  methodOne()  we print the statement and called the  methodTwo()  and the same things of calling method start until the StackOverFlowError doesn’t come. Here is the output of the following program that clears all your doubts regarding StackOverFlow Error..

Method One
Method Two
Method One
Method Two
Method One
Method Two
.
.
.
.
.
.

Exception in thread "main" java.lang.StackOverflowError
at java.base/sun.nio.cs.UTF_8$Encoder.encodeLoop(UTF_8.java:695)
at java.base/java.nio.charset.CharsetEncoder.encode(CharsetEncoder.java:578)
at java.base/sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:292)
at java.base/sun.nio.cs.StreamEncoder.implWrite(StreamEncoder.java:281)
at java.base/sun.nio.cs.StreamEncoder.write(StreamEncoder.java:125)
at java.base/java.io.OutputStreamWriter.write(OutputStreamWriter.java:211)
at java.base/java.io.BufferedWriter.flushBuffer(BufferedWriter.java:120)
at java.base/java.io.PrintStream.write(PrintStream.java:526)
at java.base/java.io.PrintStream.print(PrintStream.java:666)
at java.base/java.io.PrintStream.println(PrintStream.java:803)
at Show_StackOverFlowError.methodOne(Show_StackOverFlowError.java:16)
at Show_StackOverFlowError.methodTwo(Show_StackOverFlowError.java:22)
at Show_StackOverFlowError.methodOne(Show_StackOverFlowError.java:17)
at Show_StackOverFlowError.methodTwo(Show_StackOverFlowError.java:22)
at Show_StackOverFlowError.methodOne(Show_StackOverFlowError.java:17)

 


Working of Heap and Stack Memory :

For more understanding we are writing a java program to make you understand how Java heap and stack memory works.In the below program there are three methods main(), printString()and printNumber()these methods are used to make you understand how heap and stack memory works in Java.

public class Exp_Heap_Stack {
    public static void main(String[] args) {

        Exp_Heap_Stack obj = new Exp_Heap_Stack();

        String str = "Daily Java Concept";
        obj.printString(str);

        Integer i = 100;
        obj.printNumber(i);

    }

    private void printString(String str) {

        String s1 = "Best Java Learning Resource : ";
        System.out.print(s1);
        System.out.print(str);

    }

    private void printNumber(Integer i) {

        String s2 = " Got likes : ";
        System.out.print(s2);
        System.out.print(i);
    }
}

Output of the above program is Best Java Learning Resource : Daily Java Concept Got likes : 100 but there are some steps to understand the working of Java Memory.

Here we are giving you step by step understand of the given Java Program:

Heap Stack Working

The picture is going messy but still you can understand from this picture.

Step 1: In the first step, execution enters in main() method and executes statements, first we create a Class Object and a String Object named obj and str that is stored in Heap memory that we know that heap memory is for storage purpose and the reference of those variable are stored in Stack memory.Value of string variable stored in the String Constant pool and a reference object created in Heap.

Step 2: In Second step, the class object obj called the  printString() method and the control goes to  printString() method in Stack memory. Here two string variables str and s1 are created that variables stored in Heap and their values stored in String Constant pool.After executing print statements in  printString() method control goes to  main() method.

Step 3: Now the integer variable created and we call the  printNumber() method using class object obj.In  printNumber() method a string object s2 created and same as above value stored in String Constant pool and reference stored in Heap. After executing print statements in  printNumber() method control come back in  main() method and in last control exits from  main() method.


Can We control the Heap and Stack Memory Size:

Yes, you can.First i had written a program there to calculate the Heap Memory in terms of Max Memory,Total Memory,Free Memory and Consumed Memory.

For calculating memory spaces first we need to create the object of the Runtime classs. Runtime class available in  java.lang package and it is a Singlton Class means at a time only one object we can create.

public class Mem_Size {
    public static void main(String[] args) {

        Runtime r = Runtime.getRuntime();
        double convert_mb = 1024*1024;

        double maxMemory = r.maxMemory()/convert_mb;
        double totalMemory = r.totalMemory()/convert_mb;
        double freeMemory = r.freeMemory()/convert_mb;

        double consumedMemory = totalMemory-freeMemory;

        System.out.println("Max Memory : "+maxMemory);
        System.out.println("Total/Initial Memory : "+totalMemory);
        System.out.println("Free Memory : "+freeMemory);
        System.out.println("Consumed Memory : "+consumedMemory);

    }
}

When first time program executes the following output comes in my console:

The default value for heap size and stack size is differ from different JVMs. The best practice is always defining your own value.

Heap Size:

//This command is used to set the maximum Heap Size
java -Xmx<Size> Class_Name

//This command is used to set minimum Heap Size
java -Xms<Size> Class_Name

Here are the console result that shows you how to grow or shrink the size of Heap :

Stack Size:

We can also set the size of stack for every single thread. Because of stack memory is separate for every thread so we can set the size of every thread stack size using the following command:

//this command is used to set the stack size for every single thread
java -Xss<Size> Class_name

//command look like this:
java -Xss512K Mem_Size


Hope you will find this tutorial useful. if you need any assistance in Java or want to learn more please comment below your quires.

If you want to learn how to print print pattern programs in Java, you should follow link : Pattern Program