When executing Java code, objects are created, used and discarded repeatedly from memory. The process through which unused Java objects are discarded is called memory management but is most commonly known as garbage collection (GC).

When the Java garbage collector does its job correctly, the memory is cleaned up, before new objects are created, and it does not fill up, so you could say that the memory allocated to a program is recycled. Like the ones we’ve been writing so far, programs of low complexity do not require that much memory to function. Still, depending on their design (remember recursivity?), they could use more memory than available.

In Java, the garbage collector runs automatically. In more low-level languages, like C there is no automatic memory management.The developer is responsible for writing the code to allocate memory as needed, and deallocate it when it is no longer needed. Although it seems practical to have automatic memory management, the garbage collector can be a problem if managed incorrectly.

Garbage Collection Basics

The Java automatic garbage collection is one of the significant features of the Java Programming language. The JVM is a virtual machine used to execute Java programs. As the Java programs use resources of the system the JVM is running on top of, it has to release those resources safely. The garbage collector does this job. To understand the garbage collector, we have to take a look at the JVM architecture.

Types of Garbage Collectors

The Oracle HotSpot JVM provides the following types of garbage collectors:

  • Serial collector:

    All garbage collection events are conducted serially in one thread. Memory compaction happens after each garbage collection.

  • Parallel collector:

    Multiple threads are used for minor garbage collection. A single thread is used for a significant garbage collection and Old Generation compaction.

  • .CMS (Concurrent Mark Sweep):

    Multiple threads are used for minor garbage collection using the same algorithm as the parallel GC. Significant garbage collection is multithreaded, but CMS runs concurrently alongside application processes to minimize world events. No memory compaction is done. This type of garbage collector is suitable for applications requiring shorter garbage collection pause.That can afford to share processor resources with the garbage collector while the application is running. This was the default garbage collector until Java 8, when G1 was introduced officially as default.

  • G1 (garbage first):

    Introduced in Oracle JDK 7, update 4, was designed to replace the CMS GC permanently and is suitable for applications that can operate concurrently with CMS collector, need memory compaction, need more predictable GC pause durations, and do not require a much larger heap. The G1 collector is a server-style garbage collector, targeted for multiprocessor machines with large memories. Most laptops now have at least eight cores and 16 GB RAM it is suitable for them. G1 has concurrent (runs along with application threads—e.g., refinement, marking, cleanup) and parallel (multithreaded—e.g., stop the world) phases. Full garbage collections are still single-threaded, but if appropriately tuned properly your applications should avoid full garbage collections.

  • Epsilon no-op collector:

    Introduced in Java 11, this type of collector is a dummy GC that does not recycle or clean up the memory. When the heap is full, the JVM shuts down. This type of collector can be used for performance tests, memory allocation analysis, VM interface testing, and extremely short-lived jobs and applications that are very limited when it comes to memory usage and developers must estimate the application memory footprint as precisely as possible.

Working with GC from the Code

For most applications, garbage collection is not something a developer must take into account. The JVM starts a GC thread that does its job without hindering the application execution (usually). But for developers who want to have more than Java necessary skills, understanding how the Java garbage collection works and how can it be tuned is a must. The first thing that a developer must accept about Java garbage collection is that it cannot be controlled at runtime. As you see in the next section, there is a way to suggest the JVM that some memory cleaning is necessary, but there is no guarantee that memory cleaning is performed. The only thing that can be done is to specify some code to be run when an object is discarded.

Use the finalize() Method

Every Java class is automatically a subclass of the JDK java.lang.Object class. This class is at the root of the JDK hierarchy and is the root of all classes in an application. It provides a few useful methods that can be extended or overwritten to implement behaviour specific to the subclass. The equals(), hashcode() and toString() were already mentioned. The finalize() method was deprecated in Java 9, but it was not removed from the JDK. This method is called by the garbage collector when there are no longer any references to that object in the code. Before we move forward, let’s look at the following piece of code.

Example
		class GarbageCollection{   
		   public static void main(String args[]){  

			GarbageCollection obj=new GarbageCollection();  
			obj=null;  

			GarbageCollection a = new GarbageCollection();
			GarbageCollection b = new GarbageCollection();
			b = a;
			System.gc();  
		   }  
		   protected void finalize() throws Throwable
		   {
		        System.out.println("Garbage collection is called by JVM");
		   }
		}
Output

Garbage collection is called by JVM

Garbage collection is called by JVM

Copyright 1999- Ducat Creative, All rights reserved.