06 Java - Memory Management and Garbage Collector

06 Java - Memory Management and Garbage Collector

Photo by imgix on Unsplash

Types of Memory

There are 2 types of Memory

  • STACK

  • HEAP

Both stack and Heap are created by JVM and stored in RAM.

Stack Memory

  • Store Temporary variables and separate memory block for methods.

  • Store Primitive data types

  • Store Reference of the heap objects

    • Strong reference: The garbage collector cannot delete a memory or object if it has a strong reference.

    • Weak Reference: If the garbage collector runs and sees the weak reference, then it deletes the reference and frees the memory.

      • Soft Reference: It is a type of weak reference. The garbage collector cannot delete the soft reference object or memory unless it is very urgent, like when there is no space left in the heap memory to create objects. If the garbage collector detects space in the heap, then it won't delete the object.
// References

// 1. Strong Reference       
Person person = new Person(); 

// 2. Weak Reference       
WeakReference<Person> weakPersonObj = new WeakReference<>(new Person()); 

// 3. Soft Reference
SoftReference<Person> softPersonObj = new SoftReference<>(new Person());

  • Each thread has its own stack memory

  • Variables within a SCOPE is only visible and as soon as any variable goes out of the SCOPE, it get deleted from the stack (in LIFO order)

  • When Stack memory goes full, its throws "java.lang.StackOverflowError"

Visulization of stack:

Heap Memory

  • Store Objects.

  • There is no order of allocating the memory.

  • Garbage collector is used to delete the unreferenced objects from the heap.

    • Mark and Sweep Algorithm: First it will mark all the objects which is no more referenced and it is allowed to delete.

    • Types of GC

      • Single GC

      • Parallel GC

      • CMS (Concurrent Mark Sweep)

      • G1

  • Heap memory is shared with all the threads

  • Heap also contains the String Pool

  • When Heap memory goes full, its throws "java.lang.outOfMemoryError"

  • Heap memory is divided into:

    • Young Generation (minor GC happens here)

      • Eden

      • Survivor

    • Old/Tenured Generation (major GC happens here)

    • Permanent Generation

Metaspace

  • It is outside the heap.

  • It stores all the class variables (static variables).

  • It stores class metadata, which means it stores the information about the class from which objects can be created (blueprint).

  • It stores constants (static final).

  • When the JVM needs to load a certain class, it will load it into the metaspace. If it doesn't require it anymore, it will remove it.

  • Earlier, it was referred to as the permanent generation (permgen), which was inside the heap. It was not expandable. But now it is outside the heap and is expandable.

Visualization of stack and Heap

public class MemoryManagement {

    public static void main(String args[]){
        int primitiveVariable1 = 10;
        Person personObj = new Person();
        String stringLiteral = "24";
        MemoryManagement memObj = new MemoryManagement();
        memObj.memoryManagementTest(personObj);
    }

    private void memoryManagementTest(Person personObj) {
        Person personObj2 = personObj;
        String stringLiteral2 = "24";
        String stringLiteral3 = new String("24");

    }
}

After the scope finishes, all the stack variables and data are deleted. Only heap memory data remains, and the garbage collector takes care of it.

Structural Components of Heap Memory

Heap Memory is divided into the following way

  • Young Generation

    • Eden

    • S0

    • S1

  • Old Generation: Old generation has very heavy or big objects. They are used too frequently. Each object might have lot of references.

Garbage Collector

Working of Garbage Collector

Assuming there are 5 objects created in memory, it means that these objects will initially be placed in the Eden area. o2 and o5 don't have any references.

1st Run of GC:

Whenever the garbage collector runs, it uses the mark and sweep algorithm.

Mark: Objects o2 and o5 do not have any references. So mark these two.

Sweep: Delete the marked objects. Sweep the remaining or the surviving objects into survivor S0. Also, calculate the ages of the objects.

Also, o6 and o7 are two new objects created. So these will be placed only in Eden.

2nd Run of GC:

Apply the Mark and Sweep Algorithm:

Mark: The GC found out that o7 and o4 don't have any references. So, mark them.

Sweep: Delete the marked objects. Now sweep all the survivors into S1.

New objects o8 and o9 are also created. So, we place them in Eden.

3rd Run of GC:

Kept threshold on age as 3.

Apply Mark and Sweep:

Mark: GC found out o3 and o8 don't have any reference. So mark these 2.

Sweep: Delete the marked objects. Move all the objects to S0 because in the last step, we moved them to S1. Update the age accordingly.

Since the threshold is 3, whichever object is updated to 3 will be moved to the old generation. Hence, o1 is moved to the old generation.

Minor GC:

  • When GC runs in the young generation, it is called Minor GC.

  • Minor GC runs very frequently and periodically in the young generation.

Major GC:

  • Whenever GC running in the Old generation is called Major GC.

  • Major GC runs very infrequently and periodically in the Old generation.

Garbage Collector Algorithms

GC uses 2 types of algorithms:

  1. Mark and Sweep Algorithm: Marks all the objects that are not referenced and sweeps the objects that are marked.

  2. Mark and Sweep with Compact Memory: Assumes that there are 8 objects. If we mark 03, 04, and 06 for deletion, then after the deletion, there are some empty memory segments freed up. To store the objects effectively using compaction, we bring all the objects into one sequential segment so that no memory space is left in between. The empty memory segments will be after the compact segment.

Versions of GC

  • Serial GC: This GC works on only 1 thread. When minor GC is invoked, only 1 thread will be used. Similarly, when major GC is invoked, only 1 thread will be used.

    Parallel GC (Default in Java 8):

    Concurrent Mark and Sweep (CMS): GC threads run in parallel, and application threads also run in parallel. However, it is not 100% guaranteed. Also, there won't be any memory compaction happening.

    G1 Garbage collector: This is the same as concurrent mark and sweep, addressing all the issues. It is 100% guaranteed that application threads won't be stopped, and it also provides memory compaction.

In the newest Java version, we leverage both concurrent processing and the G1 garbage collector, resulting in reduced pause times. Consequently, throughput is enhanced while latency diminishes. Throughput refers to the rate of request processing per second, while latency denotes the delay in request processing. When only one thread is active, performance significantly slows down.

GC is very expensive: Whenever GC works start all the application threads will paused. World stops when garbage collector runs.