Understand Java memory management with these elements

CHAIRI Chaimae
4 min readJan 31, 2024

--

In Java, memory management is handled automatically by the Java Virtual Machine (JVM). When you create objects, the JVM allocates memory for them, and a garbage collector automatically identifies and frees up memory from objects that are no longer in use.

But first, why should we care about memory management?

We do care for the following reasons: preventing memory leaks, optimizing performance, troubleshooting and debugging, resource efficiency, and writing robust code, among others.

In the upcoming lines, I’ll present some key components:

Stack

It is a data storage mechanism that stores data (temporary variables, functions, procedures and references to other objects) in memory following a specific flow. It operates on the Last-In-First-Out (LIFO) algorithm. In a stack, the last element added is the first one to be removed.

In the context of memory management in Java, a stack is essential for handling various operations efficiently. The primary operations associated with a stack include:

Stack operations illustration image by @Scaler

Push: adds an element to the top of the stack. This operation is fundamental for inserting data into the memory stack.

Pop: removes the top element from the stack. This operation is crucial for retrieving and removing data from the memory stack in the reverse order of insertion.

Top: retrieves the element at the top of the stack without removing it. It allows accessing the most recently added element without altering the stack’s structure.

IsEmpty: checks whether the stack is empty. It returns a boolean value indicating whether there are any elements in the stack, which helps in conditional checks during the program’s execution.

At this point, I would like to draw your attention to the fact that the stack’s size varies since methods create and delete local variables as required. While the size is limited, the variation depends on the operating system in use.

Finally, memory is freed after it is allocated without the need to manage this allocation.

Heap

The heap is a memory area used for dynamic memory allocation, storing objects, and unlike the stack, it is not managed automatically or as tightly controlled. In the heap, you are responsible for manually freeing allocated memory when these blocks are no longer needed. Furthermore, it does not have a size limit. However, accessing objects in the heap is generally slower compared to the stack. The memory allocation begins at runtime

Heap Structure:

The heap is typically divided into two areas — the Young Space which represent the newly created objects, and the Old Space which represent long-lived objects.

The heap memory structure representation

Unreferenced Object

Unreferenced objects are subject to garbage collection. We find as examples:

Null References: In Java, objects are typically accessed through references. If a reference variable no longer points to any object (i.e., it has been assigned the value null), the object it was previously referencing becomes unreferenced.

MyClass myObject = new MyClass();  
myObject = null;

Anonymous object:

new Car();

Reference assigned to other:

Car car1 = new Car();
Car car2 = new Car();
car1 = car2;

In the example above, the first object will be available for garbage collection.

Garbage Collection

The Java Virtual Machine (JVM) includes a garbage collector that automatically reclaims memory from objects that are no longer reachable by the program. This helps to manage memory and prevent memory leaks.

The garbage collector (GC) is a background task. Its primary functions include operating discreetly in the background, releasing memory occupied by unreferenced instances, and compacting the used memory space. It is worth mentioning that the garbage collection starts by freeing the objects in the old space by FIFO.

This process becomes essential when the system requires additional memory or, typically, has a low priority. In both scenarios, the garbage collector plays a crucial role in managing memory efficiently.

By identifying and collecting unreferenced objects, it ensures that memory is reclaimed and made available for future allocations. Additionally, the compaction of memory aids in optimizing the use of available space. The garbage collector’s ability to automate these tasks alleviates developers from manual memory management, which reduces the risk of memory leaks and enhances the reliability of the software.

But what is a memory leak?

It is a situation in computer programming where a program allocates memory but fails to release or deallocate it when it is no longer needed. Over time, this can lead to a gradual increase in the consumption of a system’s memory, eventually leading to performance degradation or even system failure. Memory leaks are a common type of software bug and can occur in various programming languages, including Java.

Allocation without Deallocation: When using new in Java, it is responsible for releasing that memory when it is done using it. If the programmer forgets to release the memory or if there is a bug preventing the release, the allocated memory remains in use even if the program no longer needs it.

Unreachable Objects: Memory leaks often occur when objects are allocated but become unreachable or inaccessible by the program. If an object reference is lost or not properly managed, the garbage collector may not be able to reclaim the memory associated with that object. Moreover, memory leaks are not limited to heap memory; they can also involve other resources like file handles, network connections, or database connections.

Long-Running Applications: Even small memory leaks that occur over time can accumulate and cause problems. Meaning that continuous allocation without proper deallocation in a loop or a frequently executed part of the code can lead to a steady increase in memory usage.

To sum up, comprehension of how memory functions is fundamental in the field of software engineering. This knowledge not only facilitates the building of efficient Java applications but is also foundational for building scalable systems.

--

--

CHAIRI Chaimae
CHAIRI Chaimae

Written by CHAIRI Chaimae

This space's to document my learning and track my progress. Hope it helps someone somewhere. You're welcomed!

Responses (1)