-1

I am sorry to ask you this basic question but I am not able to understand the concept. I read many SO post but I could not understand. Could you please give me code example to understand.

  1. As said in this post

Static variables cannot be elected for garbage collection while the class is loaded. They can be collected when the respective class loader (that was responsible for loading this class) is itself collected for garbage.

I understand as per theory that Classloader cannot be collected if it has a reference but I do not understand how it is possible practically. Could you please kindly explain with a code example?

Many thanks for your help!

Learner
  • 99
  • 6

2 Answers2

1

Lets see this code to understand how classloader leaks possible

Main.java

    public class Main {
    public static void main(String...args) throws Exception {
     List<Object> list = new ArrayList<>();
    loadClass(list);
    while (true) {
        System.gc();
        Thread.sleep(1000);
      }
   }

   private static void loadClass(List list) throws Exception {
    URL url = Main.class.getProtectionDomain().getCodeSource().getLocation();
    MyCustomClassLoader cl = new MyCustomClassLoader(url);
    Class<?> clazz = cl.loadClass("com.test.Foo");
    list.add(clazz.newInstance());
    cl = null;
      }
    }

   class MyCustomClassLoader extends URLClassLoader {
     public MyCustomClassLoader(URL... urls) {
     super(urls, null);
     }
    @Override
     protected void finalize() {
    System.out.println("*** CustomClassLoader finalized!");
     }
    }

Foo.java

    public class Foo {
      public Foo() {
      System.out.println("Test ClassLoader: " + this.getClass().getClassLoader());
       }
     @Override
     protected void finalize() {
       System.out.println( this + " finalized!");
        }
    }

The output of this as follows:

Test ClassLoader: com.test.MyCustomClassLoader@71dac704

So, here we can see "*** CustomClassLoader finalized!" is not called and this is because MyCustomClassLoader is holding a reference of object list as the instances loaded by classloader are kept in it.

Now, lets change the code a bit, so here we will set list to null

 public static void main(String...args) throws Exception {
     List<Object> list = new ArrayList<>();
    loadClass(list);
    while (true) {
        System.gc();
        Thread.sleep(1000);
        list = null;
    }
  }

And now see the output

Test ClassLoader: com.test.MyCustomClassLoader@71dac704 com.test.Foo@650de12 finalized! *** CustomClassLoader finalized!

Pakira
  • 1,951
  • 3
  • 25
  • 54
  • The explanation is a bit different. An object created by class clazz is holding a reference to a class clazz. In turn, the class clazz is holding a reference to the classLoader used. Thus nothing is GCed until the reference to the object is removed from the array list – dparnovskiy Aug 24 '23 at 23:16
0

I am posting my understanding hope it helps, Background understanding: Simple way to understand this is to take an example of a Tomcat or any such application. Which is java based. Tomcat can run multiple webapps. Even if you deploy same application with different name they will be treated differently. Here these both applications will have same classes but still they are treated differently. So here comes the class loaders. So you can think in a way like Tomcat is creating a class loader for each application and loading them under it.

Reclaiming of loaders: above if Tomcat is holding reference to the loader object then the loader object will not be reclaimed. And unless loader gets garbage collected the classes loaded by it stays. So if you shutdown an application, Tomcat will ultimately drefrence it's respective loader so that gc can reclaim it an clean it including the classed loaded by it.

Quick links that may help: https://stackoverflow.com/questions/2433261/when-and-how-are-classes-garbage-collected-in-java#:~:text=A%20class%20in%20Java%20can,that%20class%20are%20still%20reachable.

https://www.dynatrace.com/resources/ebooks/javabook/class-loader-issues/#:~:text=Classloader%20Cannot%20Be%20Garbage-Collected,hold%20references%20to%20their%20classes.

Mukesh Negi
  • 31
  • 1
  • 4