Memory Management in Java
Tags: java, beginners, scope
Published: 2020-12-09 08:55:45


# 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](https://www.w3schools.com/java/java_data_types.asp)


####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
}
```

```
Array in Java: 
String[] cars = {"Volvo", "BMW", "Ford", "Mazda"};
```

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;
    }
}
```

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");
    }
}

```
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.