Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When and how are classes garbage collected in Java?

I asked a question about Garbage Collection in Java in this topic. But the answer I got, gave me another question.

Someone mentioned that classes can be collected by the garbage collector too. Is this true?

And if it is true, how does this work?

like image 921
JordyOnrust Avatar asked Mar 12 '10 14:03

JordyOnrust


People also ask

How does Java know when to garbage collect?

As long as an object is being referenced, the JVM considers it alive. Once an object is no longer referenced and therefore is not reachable by the application code, the garbage collector removes it and reclaims the unused memory.

When and how garbage collector is invoked?

When the JVM doesn't have necessary memory space to run, the garbage collector will run and delete unnecessary objects to free up memory. Unnecessary objects are the objects which have no other references (address) pointing to them.

What is garbage collection and how it works?

In the common language runtime (CLR), the garbage collector (GC) serves as an automatic memory manager. The garbage collector manages the allocation and release of memory for an application. For developers working with managed code, this means that you don't have to write code to perform memory management tasks.

What garbage collection is used in Java?

What is Java Garbage Collection? Java applications obtain objects in memory as needed. It is the task of garbage collection (GC) in the Java virtual machine (JVM) to automatically determine what memory is no longer being used by a Java application and to recycle this memory for other uses.


1 Answers

A class in Java can be garbage-collected when nothing references it. In most simple setups this never happens, but there are situations where it can occur.

There are many ways to make a class reachable and thus prevent it from being eligible for GC:

  • objects of that class are still reachable.
  • the Class object representing the class is still reachable
  • the ClassLoader that loaded the class is still reachable
  • other classes loaded by the ClassLoader are still reachable

When none of those are true, then the ClassLoader and all classes it loaded are eligible for GC.

Here's a constructed example (full of bad practices!) that should demonstrate the behaviour:

Create a bytecode file GCTester.class in a directory (not package!) x. It's source code is:

public class GCTester {   public static final GCTester INSTANCE=new GCTester();    private GCTester() {     System.out.println(this + " created");   }    public void finalize() {     System.out.println(this + " finalized");   } } 

Then create a class TestMe in the parent directory of x:

import java.io.File; import java.net.URL; import java.net.URLClassLoader; import java.lang.reflect.Field;  public class TestMe {   public static void main(String[] args) throws Exception {     System.out.println("in main");     testGetObject();     System.out.println("Second gc() call (in main)");     System.gc();     Thread.sleep(1000);     System.out.println("End of main");   }    public static void testGetObject() throws Exception {     System.out.println("Creating ClassLoader");     ClassLoader cl = new URLClassLoader(new URL[] {new File("./x").toURI().toURL()});     System.out.println("Loading Class");     Class<?> clazz = cl.loadClass("GCTester");      System.out.println("Getting static field");     Field field = clazz.getField("INSTANCE");      System.out.println("Reading static value");     Object object = field.get(null);     System.out.println("Got value: " + object);      System.out.println("First gc() call");     System.gc();     Thread.sleep(1000);   } } 

Running TestMe will produce this (or similar) output:

 in main Creating ClassLoader Loading Class Getting static field Reading static value GCTester@1feed786 created Got value: GCTester@1feed786 First gc() call Second gc() call (in main) GCTester@1feed786 finalized End of main 

In the second to last line we see that the GCTester instance is finalized, which can only mean that the class (and ClassLoader) are eligible for garbage collection.

like image 130
Joachim Sauer Avatar answered Oct 02 '22 15:10

Joachim Sauer