Memory Management in Java

cover-photo

What is Register, Heap and Stack in Java

In this article, we will see how does the Java programming language is doing memory management, we will look at registers, stack, heap, constants, non-ram memory, and the famous Java garbage collector. Let's start with the fastest storage in Java the register.

Register

The register is the fastest storage, because it exists in a different place from the other storages, in the processor. However, the number of available registers is very limited. As a developer, you don't have direct control at the registers, for comparison in C and C++ you can suggest register allocation.

Stack

The stack is located in the random-access memory (RAM) with direct support from the processor via its stack pointer. The stack pointer is moving up and down when it is going down it is creating a new memory and when it is going up it is releasing memory. This process is a very fast and great way to allocate storage, just the registers are faster in comparison.

Heap

The heap is the general-purpose pool of memory, it is also located in the random-access memory (RAM), the heap is the place where all Java objects live. The heap is a very flexible memory you can simply create a new object on the heap by writing the keyword new and the storage will be allocated on the heap when that code will be executed. The price for the flexibility is that the heap is generally slower than the stack, that's why it can take more time to allocate and the garbage collector to clean up the heap storage.

Constant

Constant value lives directly in the code because they never change, that's why they are called constants after all.

Non-RAM

There is a data that can live outside of our program, the two best examples are streamed objects, which are turned into the stream of bytes and sent to other machine and persistent objects, which the objects live on the disk so they hold their state even when the program is not running, and they can be resurrected into a regular random-access memory object when they are needed.

Java Garbage Collector

Garbage Collector in Java is running in the background and looks into all objects that are in the memory to find out objects that are not referenced. Every unreferenced objects that are found are deleted so the space can be allocated for other objects. Unlike other languages such as C where memory allocation and deallocation it's manually, in Java it's done automatically by default. Objects in Java can be unreferenced by nulling the reference, by assigning the reference to another or by anonymous object. Memory management in Java is a very broad topic here we are just scratching the surface.

Memory Management in Java example

public class Memory {

  public static void main(String[] args) { // Line 1
    int i = 1; // Line 2
    Object obj = new Object(); // Line 3
    Memory mem = new Memory(); // Line 4
    mem.foo(obj); // Line 5
  } // Line 9

  private void foo(Object param) { // Line 6
    String str = param.toString(); //// Line 7
    System.out.println(str);
  } // Line 8

}

In the image below we can see the stack and the heap with reference from the program above.

heap-and-stack-memory Java Memory Management Schema (Source: journaldev.com)

Now let's see line by line the above Java program.

  1. Java runtime creates stack memory for the main() method thread.
  2. We are declaring and initializing a primitive local variable, it is stored in the stack memory of main() method thread.
  3. We are declaring and initializing a new object, it is stored on the heap memory and the stack memory holds the reference to it.
  4. Like on the line before we are doing the same here but with a different type.
  5. We are calling foo() and a block on the top of the stack is created to be used by the foo() method, and we pass the obj.
  6. Java is passed by value, a new reference to the object is created in the foo() stack block.
  7. A new string object is declared and initialized and it is stored on the heap in and the reference is created in the foo() stack.
  8. foo() method is finished, and the memory allocated for foo() on the stack has become free.
  9. main() method is finished, and the memory allocated for main() on the stack has become free.

Conclusion

Memory management in Java is a very interesting topic but very broad topic too, Java itself will manage the memory without major interventions by the programmer, but knowing how memory work in will give you the advantage of writing good and optimized code in terms of memory usage, finding and fixing memory leaks.




#java #memory

Author: Aleksandar Vasilevski |