Select Page

Stack and Heap Memory in Java

Manoj Debnath
Published: September 21, 2022

Java data types are stored in two different forms of memory during execution: stack and heap. They typically are maintained by the underlying platform on which the Java Virtual Machine (JVM) runs.This programming tutorial provides some insights into these two memory types from the perspective of Java software development.

Want to learn how to program software in Java in more of a class or online course environment? Check our our list of the Top Online Courses to Learn Java.

How Does the Java Platform Work?

Java programs run on a platform provided by the Java Virtual Machine (JVM). This platform is the manager which provides every resource that a java application needs at runtime. This means that the program developers write – or the application that we create – have no ability to directly access system resources (be it hardware or software) unless the platform on which it runs provides it. In the case of Java, the order is something like this:

Java Virtual Machine (JVM) Tutorial

The JVM layer is what makes the Java platform independent. Other programming languages, like C/C++, do not use such a layer and, as a result, they are not platform independent per se, even though they are portable:

Java Virtual Machine Tutorial

There are many advantages and disadvantages in both cases. Since the same set of people are involved in developing the language Java and the platform JVM, the biases towards programmer convenience is obvious. This resulted in a tremendous evolution; starting as a language, today Java has become an ecosystem of its own. Meanwhile, programming languages like C/C++ are more grounded towards optimal use of the core units by being able to directly access system resources, resulting in super fast and highly efficient programs. But both have their uses in the realm of software development.

As for languages in general, there are many similarities upon which all programming languages work during compilation and execution. One of the most important of these areas is memory management. Memory management has a significant influence on the overall efficiency of the program regardless of language, because it helps manage memory resources and, therefore, application performance. The more memory used, the slower a program will be.

What is Runtime Memory in Java?

One common phenomenon among applications is the fact that every application requires some memory to work in an optimal way. This memory is provided by the underlying platform. In the case of Java, the JVM provides it (which, of course, is granted by the operating system). The typical five parts of JVM memory include: method area, heap, stack, PC register, and native memory.

Let’s focus here on the stack and heap part for now. Memory is not like a blank sheet where programmers can store data just by jotting it down. Instead, memory needs to be structured prior to its use. The stack and heap are the data structures followed when using memory. During program execution, the stored data is used for various purposes, depending on what the purpose of the program is.

The JVM decides the run time data areas used during program execution. Some data areas are JVM dependent, meaning, they are created as the JVM starts, and continue to exist throughout the life-time of the JVM. However, there are other data areas that are created and destroyed per thread. The JVM can execute multiple threads of execution at the same time. This means that each thread has its own pc (program counter) register to maintain the location of the current instruction being executed, as well as a stack to hold static memory allocations.

What is Stack Memory in Java?

The stack is a structure in memory where developers store elements (like a stack of books) in a manner that allows retrieval of data only from the top of the stack – commonly known as first-in, last-out (FILO or LIFO). Since each thread maintains a private JVM stack, it is used to store variables pertaining to their static memory allocation. The primitive variables specific to a method that we declare and use in our code are actually stored in the stack area. Also, references to objects that are actually stored in the heap memory are also stored in the stack area. So, any memory locally allocated is stored in the stack.

The default size of the stack memory can be altered using the JVM parameter -Xss. Sometimes, if too many variables are allocated or a method recursively calls itself, the stack may overflow. A common error all Java programmers are aware of is the java.lang.StackOverFlowError. This error pops up when the stack becomes full. Every method call in Java creates a new block in the stack. Therefore, a poorly designed recursive method call can easily eat up all of the stack, resulting in an overflow error.

Read: Top Online Courses to Learn Linux

What is Heap Memory in Java

The heap is a memory area that is created as soon as the JVM starts up and continues to exist until the JVM is destroyed. Unlike stack, which is a property of individual threads (as each has its own stack), heap is actually a global store managed by the JVM itself. This memory is used at runtime to allocate memory for objects. Because of this, object instantiation can be of user defined classes, JDK, or other library classes. In short, any object created with a new keyword is stored in the heap memory. The objects in the heap memory are accessible to all the threads run by the JVM. The access management is complex and uses a very sophisticated algorithm. This is where the JVM garbage collector comes into play.

The default size of the heap can be altered using the -Xms and -Xmx JVM parameters. As the number of objects are created and destroyed, the size of the heap is increased and decreased. It if reaches its maximum limit and an attempt is made for further allocation, it throws the java.lang.OutOfMemoryError.

You can learn more about garbage collection and the Java Garbage Collector (GC) in our tutorial: A Guide to Writing Garbage Collection in Java.

Java Heap StringPool

It is very interesting to note that, although it is a class, with java.lang.String, any objects instantiated from this class are handled differently. The JVM creators have found that this is the most used class in Java programming. Therefore, special attention should be given to maintain its efficiency. Moreover, string operations are always slow compared to the primitive types. So, the magic has to be there so that the use of string objects is similar to using a primitive type or close to it in terms of its efficiency and convenience in the code. Therefore, to maintain the efficiency JVM provides, a special memory region within the heap called StringPool is used. Any string objects created are stored in the StringPool by the JVM. This improves the performance manifold compared to other objects created in the heap.

Java Heap and Stack Code Example

To better illustrate the use of heap and stack memory in Java, let’s write a simple program and decide which allocation goes to which memory – heap or stack:

package project1;
import java.util.Date;
public class Main{
    public static void main(String[] args){
        int x=10;
        int y=20;
        String greet = "Hello";
        Date d = new Date();
        diff(x, y);
    }
    public static int diff(int x1, int x2) {
        return x2-x1;
    }
}

This example Java code works in the following manner:

  • The program starts and the JVM loads Java Runtime Environment (JRE) classes into the heap.
  • Upon encountering the main() method, a stack is created.
  • The local variables x and y are stored in the stack.
  • The string greet is allocated in the StringPool area of the heap.
  • The Date object is allocated in the heap area while its reference d is stored in the stack.

Java Tutorial

Read: Java Tools to Increase Productivity

Final Thoughts on Java Stack and Heap Memory

The stack and heap are two areas used by Java programs during code execution. Apart from these two, there are other memory areas, such as method area, registers, native area, and so forth. Each has their specific uses in Java applications. But, from the programmers’ point of view, stack and heap are the basic aspects of the JVM that one must understand. However a thorough understanding on all of the runtime memory specifications is always a plus and will be a topic for a future Java programming tutorial.

Read more Java programming tutorials and software development guides.

Source: www.developer.com