Tag: garbage collector in java

finalize method in Java

What is finalize() method in Java?

 

  • finalize( ) method is a method of Object class which is called just before the destruction of an object by the garbage collector.
  • After finalize( ) method gets executed completely, the object automatically gets destroyed.
  • The purpose of calling finalize method is to perform activities related to clean up, resource deallocation etc.

 

Prototype-

 

Rules for finalize() method-

 

Rule-01:

 

We can override finalize( ) method in our class based on our requirements to define our own clean up activities.

finalize( )
{
    // Clean up activities
    // Resource deallocation activities
}

 

Rule-02:

 

When garbage collector calls the finalize( ) method, it is called on that object which has to be destroyed and the finalize( ) method of corresponding class gets executed.

 

Example-

Consider the following program-

class Test
{
    public static void main(String[ ] args)                   // A "main thread" gets introduced
    {
        String s = new String("Gate Vidyalay");               // A String object gets created
        s = null;                                             // String Object becomes eligible for garbage collection
        System.gc( );                                         // A request is made to JVM for running garbage collector ; A "gc thread" gets introduced
        System.out.println("End of main method");
    }

    public void finalize( )                                   // Test class finalize( ) method
    {
        System.out.println("Finalize method of Test class");
    }
}

Output-

End of main method

 

Analysis-

 

  • In the above program, we first created a new String object and then made it eligible for garbage collection by nullifying its reference variable. We then requested the JVM to run the garbage collector for collecting the String object.
  • According to rule-02, because a String object has become eligible for garbage collection, so we expect the garbage collector to call String class finalize( ) method which is known to have empty implementation and not the finalize( ) method of Test class.
  • The output of the program clearly shows that the finalize( ) method of String class gets executed and not the finalize( ) method of Test class because the print statement of finalize( ) method of Test class does not get executed.

This justifies our rule-02.

 

Rule-03:

 

We can call the finalize( ) method explicitly based on our requirements.

If called explicitly, finalize( ) method will execute as a normal method and object will not be destroyed. The object will be destroyed only when the finalize( ) method is called by the garbage collector itself.

 

Example-

Consider the following program-

class Test
{
   public static void main(String[ ] args)         // A "main thread" gets introduced
   {
      Test t = new Test( );                        // A Test object gets created
      t.finalize( );                               // Finalize( ) method is called explicitly
      t = null;                                    // Test object becomes eligible for garbage collection
      System.gc( );                                // A request is made to JVM for running garbage collector ; A "gc thread" gets introduced
      System.out.println("End of main method");
   }

   public void finalize( )                         // Test class finalize( ) method
   {
      System.out.println("Finalize method called");
   }
}

Output-

There are two possible outputs-

Finalize method called
End of main method
Finalize method called

         OR

Finalize method called 
Finalize method called 
End of main method

 

Analysis-

 

  • In the above program, we first created a new Test object and then called the finalize( ) method explicitly which executed the finalize( ) method of Test class and “Finalize method called” got printed on the console but the object did not get destroy. This justifies our rule-03.
  • Then, we made the Test object eligible for garbage collection by nullifying its reference variable and then introduced a gc thread in the system which requested the JVM to run the garbage collector for collecting the Test object.
  • Then, two threads got introduced in the system- main thread and gc thread.
  • We can’t predict exactly which thread completes its execution first. So, two outputs are possible as shown.

 

Rule-04:

 

  • If finalize( ) method is called explicitly by the programmer and while executing that finalize( ) method if any kind of exception occurs which is uncaught i.e. no catch block is present to catch the exception, then the program will terminate abnormally by raising that exception.
  • If finalize( ) method is called by the garbage collector and while executing that finalize( ) method if any kind of exception occurs which is uncaught i.e. no catch block is present to catch the exception, then JVM will ignore that exception and rest of the program will be executed normally.

 

Example-

Consider the following program-

class Test
{
   public static void main(String[ ] args)
   {
      Test t = new Test( );                              // A Test object gets created
      t.finalize( );                                     // Statement-01 (say)
      t = null;                                          // Test object becomes eligible for garbage collection
      System.gc( );                                      // A request is made to JVM for running garbage collector
      System.out.println("End of main method");
   }

   public void finalize( )                               // Test class finalize( ) method
   {
      System.out.println("Finalize method called");
      System.out.println(10/0);                          // This statement gives rise to Arithmetic Exception
   }
}

 

Case-01: When statement-01 is not commented-

 

  • When statement-01 is not commented, t.finalize( ); statement remains active which calls the finalize( ) method explicitly.
  • Finalize( ) method tries to evaluate the expression 10/0 which gives rise to an arithmetic exception and program terminates by raising that exception as shown by the output.

 

Output-

finalize method called
"Exception in thread "main" java.lang.ArithmeticException: / by zero"

 

Case-02: When statement-01 is commented-

 

  • When statement-01 is commented, t.finalize( ); statement goes dead and thus no explicit call is made to the finalize( ) method.
  • Now, the arithmetic exception raised by the implicit call to finalize( ) method is ignored by the JVM and the rest of the program executes normally as shown by the output.
  • Two outputs are possible because two threads exist in the system – main thread and gc thread and these threads can complete their execution in any order.

 

Output-

finalize method called
End of main method

        OR

End of main method
finalize method called

 

Rule-05:

 

Garbage collector calls the finalize( ) method only once on any object even though that object becomes eligible for garbage collection multiple times.

 

Get more notes and other study material of Core Java.

Watch video lectures by visiting our YouTube channel LearnVidFun.

Garbage Collection in Java

What is Garbage Collection in Java?

 

In Java, the unreferenced objects not having any reference to them are referred to as garbage as they are useless.

The process of collecting the unreferenced objects (garbage) to free up the unnecessarily occupied memory for efficient memory usage is called as garbage collection.

In Java, there is a program called as Garbage Collector which has been assigned the responsibility of Garbage Collection.

 

 

This ignorance of destruction of useless objects often fills the memory unnecessarily and as a result of which at certain point of time, sufficient memory does not remain available for the creation of new objects and the performance of entire application goes down due to memory problems like OutOfMemoryError.

To avoid such problems, it is very important to perform garbage collection from time to time.

 

Purpose of Garbage Collector-

 

  • Unlike in old programming languages like C++ where programmer has the responsibility of both creating as well as destroying the objects, in Java, programmers are allowed to create as many objects as they want without any overhead of destroying the useless objects.
  • Garbage Collector takes up the responsibility of cleaning up the memory by destroying the useless objects.
  • Garbage Collector runs from time to time in the background silently to clean up the memory.

 

Eligibility Criteria for Garbage Collection-

 

  • Although, programmers have no responsibility of destroying the useless objects, it is highly recommended that if there are some existing objects which are no longer required, programmers make those objects eligible for the garbage collection so that they can be easily identified by the garbage collector for garbage collection.

 

An object qualifies for garbage collection if and only if it does not contain any external reference to it

 

 

Requesting JVM to run Garbage Collector-

 

  • We can not predict when JVM will perform the garbage collection by running its garbage collector. It entirely depends on the JVM and varies from JVM to JVM.
  • So, an object may not be destroyed immediately after it has qualified for the garbage collection. It will be collected only when the JVM will run its garbage collector.
  • Instead of keep waiting for the JVM to run the garbage collector by itself, we can manually make a request to the JVM for collecting the garbage.
  • However, it totally depends on the JVM whether it accepts the request or not. However, JVM mostly accepts the request for running the garbage collector.

 

Ways to request JVM for running Garbage Collector-

 

There are 2 ways in which the JVM can be requested to run its garbage collector-

 

 

1. By using System class-

 

  • System class contains a static method gc( ) which can be used to request the JVM  to run its garbage collector.
  • Syntax-

System.gc( ) ;

 

2. By using Runtime class-

 

  • Runtime class is a singleton class contained in a java.lang package.
  • It is possible for a java application to communicate with the JVM by making use of a Runtime object which can be created by using getRuntime( ) method as-

Runtime obj = Runtime.getRuntime( ) ;

  • Once we have created a Runtime object, the methods given below can be called on it-

 

a. freeMemory( )-

  • This method returns the amount of free space in the heap in bytes.

b. totalMemory( )-

  • This method returns the total heap size in bytes.

c. gc( )-

  • This method requests the JVM to perform the garbage collection by running its garbage collector.

 

NOTE-

 

  • gc( ) method contained in System class is static in nature i.e. it is a static method whereas gc( ) method contained in Runtime class is an instance method.

 

Which of the above two ways is recommended?

 

As per the convenience, it is recommended to use System.gc( ) method when compared to Runtime class gc( ) method.

As per the performance performance, it is recommended to use Runtime class gc( ) method when compared with System class gc( ) method because Runtime class gc( ) method calls System.gc( ) method internally.

 

class System
{
   public static void gc( )
   {
      Runtime.getRuntime( ).gc( );
   }
}

 

By using Runtime class gc( ) method directly, a method call is saved which contributes towards improving the performance.

 

EXAMPLE-

import java.util.Date; 
class RuntimeExample
{
   public static void main (String[ ] args)
   {
      Runtime obj = Runtime.getRuntime( ); 
      System.out.println(obj.totalMemory( ));
      System.out.println(obj.freeMemory( )); 

      for(int j=0 ; j<10000 ; j++)
      {
         Date d = new Date( ); 
         d = null; 
      }

      System.out.println(obj.freeMemory( ));
      obj.gc( );
      System.out.println(obj.freeMemory( ));
   }
}

OUTPUT-

5177344

4945200

4714464

5059352

 

PROBLEM BASED ON GARBAGE COLLECTION IN JAVA-

 

Problem-

A student learning Java states the following 4 ways in which the JVM can be requested for running its Garbage Collector-

  1. Runtime.getRuntime( ).gc( );
  2. Runtime.gc( );
  3. (new Runtime( )).gc( );
  4. System.gc( );

Which of the above four ways is / are correct?

  1. Only I and IV
  2. Only I
  3. Only IV
  4. All are correct

 

Solution-

Option (A) is correct.

  • II is incorrect because gc( ) method contained in Runtime class is not static in nature.
  • III is incorrect because Runtime class is a singleton class, so an object can not be created for it by using the new operator.

 

Get more notes and other study material of Core Java.

Watch video lectures by visiting our YouTube channel LearnVidFun.