introduce

  • In C/C++, the programmer is responsible for the creation and destruction of objects. Usually programmers ignore the destruction of useless objects. Because of this oversight, at some point, not enough memory may be available to create new objects, and the entire program will terminate unexpectedly, resulting in OutOfMemoryErrors.
  • But in Java, the programmer doesn’t need to care about all the objects that are no longer used. The garbage collection mechanism automatically destroys these objects.
  • The garbage collection mechanism is the best example of a daemon thread because it is always running in the background.
  • The primary goal of garbage collection is to free heap memory by destroying unreachable objects.

Important Terms:

  1. Unreachable object: An object is said to be unreachable if it does not contain any reference to it. Also note that objects belonging to the quarantine island are not accessible.
Integer i = new Integer(4);
// The new Integer object is accessible by reference in 'I'
i = null;
// The Integer object is no longer available.
Copy the code

  1. Eligibility for garbage collection:If an object is unreachable, it is said to be eligible for GC. In the figure above, inI = null;Integer object 4 in the heap area is eligible for garbage collection.

A way to make an object conform to GC conditions

  • Even if the programmer is not responsible for destroying useless objects, it is strongly recommended to make objects inaccessible (and therefore eligible for GC) if they are no longer needed.

  • There are generally four different ways to make an object suitable for garbage collection.

  1. Dereference variable
  2. Reassign reference variables
  3. An object created inside a method
  4. Isolated island

All of the above methods with examples are discussed in a separate article: How do I make objects garbage collection eligible

How to request the JVM to run the garbage collector

  • Once we have made an object eligible for garbage collection, the garbage collector may not destroy it immediately. Every time the JVM runs the garbage collector, only objects are destroyed. But when the JVM runs the Garbage Collector, we don’t know.

  • We can also ask the JVM to run the garbage collector. There are two ways to do this:

  1. useSystem.gc()methods: The system class contains static methodsgc()Used to request the JVM to run the garbage collector.
  2. Use the runtime.geTruntime ().gc() method: The run-time class allows the application to interact with the JVM that is running the application. Therefore, by using its GC () method, we can ask the JVM to run the garbage collector.
// Demonstrate a Java program that asks the JVM to run the garbage collector
public class Test
{
	public static void main(String[] args) throws InterruptedException
	{
		Test t1 = new Test();
		Test t2 = new Test();
		
		// Dereferencing variables
		t1 = null;
		
		// Ask the JVM to run the garbage collector
		System.gc();
		
		// Dereferencing variables
		t2 = null;
		
		// Ask the JVM to run the garbage collector
		Runtime.getRuntime().gc();
	
	}
	
	@Override
	Finalize method is called once on the object before garbage collection
	protected void finalize(a) throws Throwable
	{
		System.out.println("Garbage collector call");
		System.out.println(Object Garbage collection: + this); }}Copy the code

Output:

The garbage collector calls object garbage collection: haiyong.Test@7ad74083 The garbage collector calls object garbage collection: haiyong.Test@7410a1a9Copy the code
  • Notes:
    1. There is no guarantee that either of the above methods will run the garbage collector.
    2. callSystem.gc()Equivalent to calling:Runtime.getRuntime().gc()

finalized

  • Just before destroying an object, the garbage collector calls the Finalize () method of the object to perform the cleanup activity. Once the Finalize () method completes, the garbage collector destroys the object.

  • The Finalize () method exists in Object classes with the following archetypes.

protected void finalize(a) throws Throwable
Copy the code

Depending on our requirements, we can override the Finalize () method to perform our cleanup activities, such as closing the database connection.

Notes:

  1. The garbage collector, not the JVMfinalize()Methods. The garbage collector is one of the modules of the JVM.
  2. Object classfinalize()Method is not available, so override is recommendedfinalize()Method to process system resources or perform other cleanups.
  3. For any given object,finalize()Methods are never called more than once.
  4. iffinalize()Method throws an uncaught exception, ignores the exception and terminates the object.

For an example of the Finalize () method, see garbage collection for the tenth set of output for a Java program

Let’s take a real world example where we use the concept of garbage collector.

Let’s say you go to Bytedance for an internship and they tell you to write a program that counts the number of employees working at the company (not including interns). To make this program, you must use the concept of garbage collector.

This is the actual task you get in the company: –

Q: Write a program to create a class named Employee that has the following data members. 1. An ID that stores the unique ID assigned to each employee. 2. Employee name. 3. Age of employees.

In addition, provide the following methods –

  1. Parameterized constructor to initialize the name and age. ID should be initialized in this constructor.
  2. The method show() displays the ID, name, and age.
  3. The method showNextId() displays the ID of the next employee.

Now, a novice with no knowledge of garbage collection might write code like this:

// A procedure for calculating the number of employees working in a company

class Employee
{
	private int ID;
	private String name;
	private int age;
	private static int nextId=1;
	// It is static because it remains common across and shared by all objects
	public Employee(String name,int age)
	{
		this.name = name;
		this.age = age;
		this.ID = nextId++;
	}
	public void show(a)
	{
		System.out.println
		("Id="+ID+"\nName="+name+"\nAge="+age);
	}
	public void showNextId(a)
	{
		System.out.println
		("Next employee id will be="+nextId); }}class UseEmployee
{
	public static void main(String []args)
	{
		Employee E=new Employee("GFG1".33);
		Employee F=new Employee("GFG2".45);
		Employee G=new Employee("GFG3".25);
		E.show();
		F.show();
		G.show();
		E.showNextId();
		F.showNextId();
		G.showNextId();
			
			{ // This is the subblock that holds all interns.
			Employee X=new Employee("GFG4".23);	
			Employee Y=new Employee("GFG5".21);
			X.show();
			Y.show();
			X.showNextId();
			Y.showNextId();
		}
		// After this brace, X and Y are removed. So it should now show nextId as 4.
		E.showNextId();// The output of this line should be 4, but it will give 6 as output.}}Copy the code

Output:

Now get the correct output: Now the garbage collector (GC) will see two free objects. Now decrement nextId, and gc(Garbage Collector) will only call the method Finalize () if our programmer overwrites it in our class. As mentioned earlier, we must request the GARBAGE Collector, and to do so, we must write the following three steps before closing the braces on the subblock.

  1. Set the reference to null (i.e. X = Y = null;)
  2. Call System. The gc ();
  3. Call System. RunFinalization ();

Correct code to now count the number of employees (excluding interns)

// The correct code to calculate the number of employees excluding interns
class Employee
{
	private int ID;
	private String name;
	private int age;
	private static int nextId=1;
	// It is static because it remains common across and shared by all objects
	public Employee(String name,int age)
	{
		this.name = name;
		this.age = age;
		this.ID = nextId++;
	}
	public void show(a)
	{
		System.out.println
		("Id="+ID+"\nName="+name+"\nAge="+age);
	}
	public void showNextId(a)
	{
		System.out.println
		("Next employee id will be="+nextId);
	}
	protected void finalize(a)
	{
		--nextId;
		// In this case, GC will call Finalize () twice for both objects.}}// This is the closing bracket of the Employee class
class UseEmployee
{
	public static void main(String []args)
	{
		Employee E=new Employee("GFG1".33);
		Employee F=new Employee("GFG2".45);
		Employee G=new Employee("GFG3".25);
		E.show();
		F.show();
		G.show();
		E.showNextId();
		F.showNextId();
		G.showNextId();
			
		{
			// This is the subblock that holds all interns.
			Employee X=new Employee("GFG4".23);	
			Employee Y=new Employee("GFG5".21);
			X.show();
			Y.show();
			X.showNextId();
			Y.showNextId();
			X = Y = null; System.gc(); System.runFinalization(); } E.showNextId(); }}Copy the code

Output:

😊 end of want to say

You just have to code it and try it out. If you have any trouble understanding or using the code, please ask in the comments below.

I’ve been writing a tech blog for a long time, mostly through Nuggets, and this is one of my tech articles/tutorials. I like to share technology and happiness through articles. Please visit my blog: Haiyong for more information. Hope you like it! Here is a summary of all my original and work source: GitHub

If you do learn something new from this post, like it, bookmark it and share it with your friends. 🤗 Finally, don’t forget ❤ or 📑 for support