DEV Community

Cover image for Memory Management in Java
Nana-hawau
Nana-hawau

Posted on • Updated on

Memory Management in Java

Table Of Contents

  • Introduction
  • What are variables?
  • Memory Management in Java
  • Conclusion

Introduction

Memory management is an important part of any programming language. It's the process in which data values are created in a part of memory during the course of running your program and efficiently discarded after use to free up space for the running program. Non C programmers do not have to bother with this, but it's important to have an inkling of how this process works.

What are variables?

Variables are label containers for storing data values. Think about it like a container in which you store something important. It's important to give it a memorable name, a name related to the contents of the container. So when you go back to it in a few weeks your brain can make the association between the content and the name without fuss.

Programming languages divide data types into two groups: Primitive types and Reference types.

Primitive Types

Data Type Size Description
byte 1 byte Stores whole numbers from -128 to 127
short 2 bytes Stores whole numbers from -32,768 to 32,767
int 4 bytes Stores whole numbers from -2,147,483,648 to 2,147,483,647
long 8 bytes Stores whole numbers from -9,223,372,036,854,775,808 to 9,223,372,036,854,775,807
float 4 bytes Stores fractional numbers. Sufficient for storing 6 to 7 decimal digits
double 8 bytes Stores fractional numbers. Sufficient for storing 15 decimal digits
boolean 1 bit Stores true or false values
char 2 bytes Stores a single character/letter or ASCII values

Source: Java Data Types

Reference Types

These are arrays, strings, classes, interfaces etc.

public Class Person {
private String firstName;
private String lastName;

public Person (String firstName, String lastName) {
this.firstName = firstName;
this.lastName = lastName;
}

// Getters and Setters
}
Enter fullscreen mode Exit fullscreen mode
Array in Java: 
String[] cars = {"Volvo", "BMW", "Ford", "Mazda"};
Enter fullscreen mode Exit fullscreen mode

There are major differences between these two. But the difference of interest in this article is their storage in memory.

Memory Management in Java

Memory management is the process of allocation and deallocation of memory in Java. The Java Virtual Machine (JVM) handles this process. Java uses an automatic memory management system called a garbage collector. Users of the language very rarely have to perform this action themselves. Although, there is a gc() static method in the System class for requesting that the JVM run the garbage collector.

Memory in java is divided into two: The stack and the heap memory. If you are familiar with data structures, then you have heard of stacks. Stacks are dynamic data structures that follow the Last In First Out (LIFO) paradigm. The last item to be inserted into a stack is the first one to be deleted from it, the stack memory space follows this principle. There is no relationship between the heap data structure and the heap memory space. The heap is the bigger of the two memory spaces in Java. It is a large memory space that contains values of objects created in a program.

Stack memory holds the definitions and values of primitive data types. When a primitive data type is created, the variable name and value is stored in the stack. Primitive data types are short lived and only exist in the code block (scope) in which they are defined. After the program exits that block, they are removed from the stack and cease to exist.

public class Test {
    public static void main(String[] args) {
        int intValue = 5;
        System.out.println(incrementInt(intValue));
        System.out.println(intValue);
    }

    public static int incrementInt (int intValue){
        intValue = intValue * 5;
        return intValue;
    }
}
Enter fullscreen mode Exit fullscreen mode

The value of intValue remains 5. This is because variables defined in a method have method level scope (i.e. They only exist in the method) and cannot be accessed outside of the method block. A copy of intValue is made and passed into the incrementInt method. When the program enters the incrementInt method block, it is that copy that is incremented and on exit from the method block, the variable value is popped off the stack and discarded.

The stack memory has a definite size. Inefficient code such as a function invoking itself endlessly (infinite recursion) could cause a stack overflow - a situation where the stack runs out of memory.

Reference variables are stored differently. When a reference variable is created: A reference to the object is created and stored in the stack while the value is stored in the heap. This reference is the memory address of the object in the heap. This is why objects can be referenced across multiple code blocks.

Instantiating the Class Person defined earlier and passing it across multiple code blocks

public class Test {
    public static void main(String[] args) {
      Person newPerson = new Person("Nana", "Hawau");
      changeFirstName(newPerson);
      System.out.println(user.getFirstName())
    }

    public static void changeFirstName (User user){
        user.setFirstName("Ali");
    }
}

Enter fullscreen mode Exit fullscreen mode

The variable newPerson is kept in the stack memory as a reference to the object value in the heap memory. In this instance, a copy of the reference on the stack is made and pointed to the value of the object on the heap. So when the program enters the changeFirstName method, the new reference made points to the same object on the heap. Any change made on the object will affect all instances of the object across multiple code blocks. The program prints Ali in this case. Reference data types are only garbage collected when a reference to them no longer exists on the stack.

Conclusion

The JVM uses this efficient technique of garbage collection to keep track of data in order to remove them from a program when they have become redundant.

Top comments (3)

Collapse
 
elderjames314 profile image
James Oladimeji

Very educative post. In summary:
Primitive and reference variables are stored on the Stack, while the objects are stored on the heap. And the good news for Java developers, you don't have to bother by destroying objects after use, the almighty JVM takes care that for us under the hook.

Collapse
 
nanahawau profile image
Nana-hawau

Exactly!!

Some comments may only be visible to logged-in visitors. Sign in to view all comments.