|
The Java Language Specification
A class or interface may be unloaded if and
only if its class loader is unreachable. Classes loaded by the bootstrap
loader may not be unloaded.
Rationale
Class unloading is an optimization that helps reduce memory use. Obviously,
the semantics of a program should not depend on whether and how a system
chooses to implement an optimization such as class unloading. To
do otherwise would completely compromise the portability of Java programs.
Consequently, whether a class has been unloaded or not should be transparent
to a Java program.
However, if a class is unloaded while its loader is reachable, it may
be reloaded. There is no way to be sure that this will not happen. Even
if the class is not referenced (even symbolically) by any class
that is currently loaded it may be referenced by some not yet loaded class.
When this class is loaded, its execution may cause reloading of the unloaded
class.
Reloading may not be transparent if, for example, the class has:
-
Static variables (whose state may be lost).
-
Static initializers (which may have side effects).
-
Native methods (which may retain static state).
Even this is not enough, since the hash value of the Class object
is dependent on the Class object's identity. So, it is virtually
impossible to reload a class in a completely transparent manner.
Since we can never guarantee that unloading a class whose loader is
reachable will not cause reloading, and reloading is never transparent,
and unloading must be transparent, it follows that one must not unload
a class while its loader is still reachable.
A corollary is that classes loaded by the bootstrap loader can never
be unloaded.
This turns out not be a problem. Class unloading is an optimization
that is only significant for applications that load large numbers of classes
and that stop using most of those classes after some time. A prime example
of such an application is a web browser, but there are others. A characteristic
of such applications is that they are managing classes through explicit
use of class loaders. As a result, the policy outlined above works well
for them.
Furthermore, in JDK 1.2, not only applets but applications and system
extensions use class loaders as well. So the only classes that are
never unloaded are those classes loaded by the bootstrap loader. The memory
overhead of these classes need not be large. Finally, implementations are
free to optimize the storage management of loaded classes in a variety
of ways
besides class unloading.
Strictly speaking, it was never essential that the issue of class unloading
be discussed by the Java Language Specification, as it is an optimization.
However, it is a subtle issue, and so it was mentioned by way of clarification.
Unfortunately, misunderstandings arose, aggravated by the the class unloading
behavior of JDK 1.1. This behavior was not mandated by the Java Language
Specification. Indeed, it contradicted the specification; it was simply
a bug. The bug has been fixed in JDK 1.2, and the specification clarified
to avoid such misunderstandings in the future.
|