Heap and Stack

Kaan Caki
Insider Engineering
4 min readAug 27, 2024
Heap and Stack

They are two different memory areas used in the runtimes of programming languages. Stack is a pile on top of each other and is a more controlled pile, while heap is a random pile and is more difficult to control.

Heap

It is the memory area used by the JVM to store objects. It is also known as the dynamic memory area. It is much larger than the stack, and it is the first thing that comes to mind when talking about memory leak.

Stack

It is the place where the areas reserved for the active methods currently running in the program are located. It works as last-in, first-out (LIFO). That’s why it is also called call the stack.

The memory area of ​​each method on the stack is called a frame, and frames are opened one after the other on the stack. In Java, the main window always opens first on the stack. Continuing from Main, it continues by opening a new frame at the top of the stack for each new method called. When the method finishes executing, the frame on the stack is deleted as it returns to the calling method, thus the frames on the stack are deleted in the reverse order of opening. Finally, the memory window of the last main method is also cleared and the JVM stops. We said that each frame is for a method, it is the memory area that holds the local variables in that method. That’s why local variables are also called stack variables. Stack size depends on the number and size of memory-consuming structures. When the stack is deleted, all data in it is also deleted.

While objects are created on the heap, local variables are created on the stack.

Local Variables and Stack

Local variables are also given the following names:

-Stack Variables: While objects are created in the heap, local variables are created in the stack.
-Automatic Variables: They are recreated every time the block they are in is entered and become inaccessible when exited.
-Temporary Variables: Their lifetime is the same as the lifetime of the block they are in, but the lifetime of object variables is determined by the lifetime of the object.

Type and Role of the Variable

Whether a variable is local or a member determines its role, regardless of its type. The role of a variable is related to how that variable is used. For example, if a primitive variable acts as a member variable, it will be in the object’s address space in the heap, while a reference defined in a method will be in the stack in memory. However, the object that this reference points to will always be on the heap.

Local or member is a property that is determined independently of the type of variable. What matters is its role; for example, primitive variables like speed or distance can act as member variables because they define the car object. A primitive variable like age also identifies a person, while a string like name identifies the name of a person; both are functionally instance variables (object variables), but name is of a complex type while age is of a primitive type. Its role determines where it is located in terms of memory: Member variables reside in the object on the heap, while local variables created in a method reside on the stack.

The main issue is the functionality of the variable: instance variables that are part of the object are always on the heap, regardless of their type. Local variables always reside on the stack, again regardless of their type.

Here’s a simple and understandable Java code example that demonstrates the concepts of heap and stack:

public class BankAccount {
// Account balance, resides in the heap
private double balance;

public BankAccount(double initialBalance) {
this.balance = initialBalance;
}

public void deposit(double amount) {
// amount is a local variable, resides in the stack
balance += amount;
}

public void withdraw(double amount) {
// amount is a local variable, resides in the stack
if (amount <= balance) {
balance -= amount;
} else {
System.out.println("Insufficient funds");
}
}

public double getBalance() {
return balance;
}

public static void main(String[] args) {
// Creating a BankAccount object, which resides in the heap
BankAccount myAccount = new BankAccount(1000);
// Deposit money, local variable 'amount' interacts with heap variable 'balance'
myAccount.deposit(500);
// Withdraw money, local variable 'amount' interacts with heap variable 'balance'
myAccount.withdraw(200);
System.out.println("Current balance: " + myAccount.getBalance());
}
}
  • In this example, the balance is a member variable (instance variable) of the BankAccount class. It is allocated in the heap memory when an object of BankAccount is created.
  • The amount variable in the deposit and withdraw methods is a local variable defined inside these methods. It is allocated in the stack memory when the method is called.
  • The methods deposit and withdraw demonstrate the interaction between local variables (amount, residing in the stack) and member variables (balance, residing in the heap). For instance, when you deposit or withdraw money, the amount (a stack variable) updates the balance (a heap variable), showing how data is transferred between different memory regions.
  • In the main() method, an object of BankAccount is created (BankAccount myAccount = new BankAccount(1000);). This object and its member variables (including balance) reside in the heap.

This example illustrates how local variables are created on the stack and are short-lived, existing only during the execution of the method where they are defined. In contrast, member variables exist for the lifetime of the object they belong to and are stored in the heap memory.

You can also follow our Insider Engineering Blog for more articles where we detail our engineering processes. Also, I think you might be interested in this topic, you should definitely check it out: Vector Search for Newborns 👶

--

--