Skip to Main Content

Java HotSpot Virtual Machine

Announcement

For appeals, questions and feedback about Oracle Forums, please email oracle-forums-moderators_us@oracle.com. Technical questions should be asked in the appropriate category. Thank you!

Forcing JVM to unload bytecode at runtime, to allow reloading of new class?

843811Aug 24 2002 — edited Aug 26 2002
Hi all,

I would like to know a few things about classes once they are loaded. I believe a loaded class is nothing more than an Object in terms of its lifecycle, correct? If so, then to make a class "unload", you simply have to make sure there are no references to the class correct? So, what are the rules for making sure nothing references a class instance?

Below I'll list a couple of examples. In Example 1 below, I have class A, B and C. Class A creates a instance variable to class B. In the constructor of class A, it creates a temporary class C, passing to it a reference of itself, which C stores in a local variable. Now, in class C, since it is only created in a Constructor (or method) in class A, it goes out of scope at the end of the method/constructor, and thus its reference to class A is no longer any good, correct? Therefore, at this point, there are no references to class A and thus setting A = null (assuming a "central" class loads class A, B and C like a plugin engine would do) should properly dispose of class A. I know, the GC does NOT necessarily remove the class A bytecode from memory right away. So I guess a question here is in need. When does the class A bytecode actually get removed from the JVM memory, in such a way that a "new" call to create it would effectively tell the JVM to have to open the .class file, read its byte code and create a new instance of it in memory? The purpose of these questions is to figure out how, at runtime to reload a class AND get the actual new version of the code. The reason is, if you do everything possible to unload a class, but the JVM doesn't discard the bytecodes of the class before you tell it to load the same class, it will use the "old" bytecode it has in memory, rather than load the bytecode off the HD or URL location and discard the old bytecode. I need a way to get the JVM to discard the bytecode to reload a newer version of a class. But the reason for the examples below is to also help me understand how a class is actually permitted to be unloaded by the JVM. This is also so that the JVM is not wasting memory with multiple versions of the same class, if it even does that. I want to definitely reclaim any memory used by the older version of the class, before loading a newer version.

So, in example 2 below, the situation changes slightly. A is now keeping a reference to the class C it creates in the constructor. Because C also creates a reference back to A since the A instance is passed in to C's constructor, A can now not be freed and made available for unloading until the reference to A in C is set to null, is this correct? I seem to lack basic understanding of how the whole reference counting thing works for objects and when a JVM can actually unload the bytecode of an object, thus freeing up memory. I suppose a good book on the JVM would clear this up, but I am hoping one of you reading this will know and can help me understand this process. So in this example, am I correct in that the C reference to A must be set to null, then the A instance must be set to null to tell the JVM there is no more use for the A class? I do realize that if other classes also use A, that the bytecode for A would be kept in memory. Let's assume this is the only use of A, B and C (and looking at the examples, B serves no real purpose anyway, but I already wrote it down so I'll leave it).

So once again, my goal here is to understand the lifecycle of an object, specifically a Class object (they are one and the same, correct, in terms of lifecycle?), and when the JVM actually removes the bytecode from memory so that if a new version of the same class is now available at runtime, the JVM loads the new bytecode into memory.


Thanks very much for taking the time to read this and reply.

Example 1:

class A
{
B b = new B();

public A()
{
C c = new C(this);
}
}

class B
{
public B()
{
}
}

class C
{
A a = null;

public C(A a)
{
this.a = a;
}
}

Example 2:

class A
{
B b = new B();
C c = null;

public A()
{
c = new C(this);
}
}

class B
{
public B()
{
}
}

class C
{
A a = null;

public C(A a)
{
this.a = a;
}
}
Comments
Locked Post
New comments cannot be posted to this locked post.
Post Details
Locked on Sep 23 2002
Added on Aug 24 2002
7 comments
1,197 views