The Java language specification speaks of a mechanism for loading, unloading, and reloading classes in detail.
Downloading refers to the process of finding a binary form of type class or interface with a specific name, possibly by calculating it on the fly, but usually by obtaining a binary representation previously computed from the source code, the compiler and building a class object from this binary form to represent class or interface.
The exact semantics of loading are given in Chapter 5, Java Virtual Machine Specifications (whenever we refer to the Java Virtual Machine specification in this book, we mean the second edition as amended by JSR 924). Here we provide an overview of the process in terms of the Java programming language.
The binary format of a class or interface is usually the class file format described in the Java Virtual Machine Specification above, but other formats are possible provided that they meet the requirements specified in ยง13.1. The defineClass of class ClassLoader can be used to build class objects from binary representations in the class file format.
In certain circumstances, you can unload classes and interfaces, which can cause an unpredictable reboot.
An implementation of the Java programming language can unload classes. A class or interface can be unloaded if and only if its defining class loader can be returned by the garbage collector, as described in section 12.6. Classes and interfaces loaded by the boot loader cannot be unloaded.
Class offloading is an optimization that helps reduce memory usage. Obviously, the semantics of the program should not depend on how and how the system decides to implement optimization, such as class unloading. . Otherwise, it may jeopardize portability of the programs. Therefore, regardless of whether the class or interface was unloaded or not, it should be transparent to the program.
However, if a class or C interface was unloaded, while its defining loader was potentially available, C could be reloaded. It can never be guaranteed that this will not happen.
In fact, he went to your specific problems:
Rebooting may not be transparent if, for example, the class has:
- Static variables (whose state will be lost).
- Static initializers (which may have side effects).
- Native methods (which can maintain a static state).
In addition, the hash value of a class object depends on its identity. Therefore, as a rule, it is not possible to completely reload a class or interface.
Since we can never guarantee that unloading a class or interface whose loader is potentially available will not result in a reboot, and reloading will never be transparent, but unloading must be transparent, it follows that you cannot unload a class or interface while its loader potentially achievable. A similar line of reasoning can be used to deduce that classes and interfaces loaded by the boot loader can never be unloaded.
It should also be argued why it is safe to unload class C if its defining class loader can be restored. If the defining loader can be restored, then there can never be any live links to it (this includes links that are not live, but can be resurrected by finalizers). This, in turn, can be true only if there can never be any live links to any of the classes defined by this loader, including C, either from their instances or from the code.
Class unloading is an optimization that is important only for applications that load a large number of classes and which stop using most of these classes after a while. A striking example of such an application is a web browser, but there are others. A characteristic feature of such applications is that they manage classes through the explicit use of class loaders. As a result, the policies outlined above work well for them.
Strictly speaking, it is not important that the problem of class unloading is discussed by this specification, since class unloading is just an optimization. However, the question is very subtle, and therefore it is mentioned here by way of clarification.