1

Hello guys, when I watched presentation about G1GC, I learned, that this GC can make unload of the class, during collecting garbages. Lets imagine, that we have such a class.

public class Foo {
   public static int a = 5;

}

And lets assume that we haven't got any reference to this class in our code, to make it clear for GC that this class wouldn't be used any more. To make class loading and initialization happens, we access periodically this int a variable. To not have any reference in code, we do this variable accession by reflection, in the method invoked by http request with the class name as a param.

Is it possible in such a case, or any similar case, to have class initialized many times and what also means that static field will be initialized many times?

Can the static field can be initialized few times?

MyWay
  • 1,011
  • 2
  • 14
  • 35
  • This may be helpful: https://stackoverflow.com/questions/148681/unloading-classes-in-java – tgdavies Dec 10 '20 at 00:37
  • The static field is not being initialised more than once: New instances of the class are being created, which contain new instances of the static field's value. In your example you do have a reference to the class, even if you only access it reflectively, via the class loader which loads it. – tgdavies Dec 10 '20 at 00:38
  • @Holger could you put this comment as an answer? Because it's just in point and I would like to mark it. I would be grateful, if you could elaborate, is possible situation, that we have multiple classloaders in one application? (not one JVM) Why this feature (class unloading) is useful? Only during redeploy of application, to garbage classloader of destroyed application, without restarting application server? – MyWay Dec 10 '20 at 19:50

2 Answers2

3

That’s addressed in the specification in §12.7. Unloading of Classes and Interfaces:

An implementation of the Java programming language may unload classes.

A class or interface may be unloaded if and only if its defining class loader may be reclaimed by the garbage collector as discussed in §12.6.

Classes and interfaces loaded by the bootstrap loader may not be unloaded.

with the motivation for the rule directly connected to your question:

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 compromise the portability of programs. Consequently, whether a class or interface has been unloaded or not should be transparent to a program.

Reloading may not be transparent if, for example, the class has static variables (whose state would be lost), static initializers (which may have side effects), or native methods (which may retain static state). Furthermore, the hash value of the Class object is dependent on its identity. Therefore it is, in general, impossible to reload a class or interface in a completely transparent manner.

Since we can never guarantee that unloading a class or interface whose loader is potentially reachable will not cause reloading, and reloading is never transparent, but unloading must be transparent, it follows that one must not unload a class or interface while its loader is potentially reachable. A similar line of reasoning can be used to deduce that classes and interfaces loaded by the bootstrap loader can never be unloaded.

Besides the explicitly mentioned bootstrap loader (which needed an explicit statement as it is represented by null, so reachability is meaningless), the application class loader, also known as system class loader is always reachable. The same applies to its parent, the extension class loader prior to JDK 9 and the platform class loader since then.

The implication is that for ordinary applications loaded by the application loader and all of its direct dependencies, class unloading simply is impossible. Only additional class loaders created by the application or a framework may become unreachable.

The specification cited above also says:

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 manage classes through explicit use of class loaders. As a result, the policy outlined above works well for them.

The example reflects the history of Java but today, a prime example would rather be an application server. When redeploying a new version or even when loading the same class files again with a new class loader, they’re technically different classes and the transparency of unloading is not relevant.

This is covered by the virtual machine specification, §5.3. Creation and Loading which states:

At run time, a class or interface is determined not by its name alone, but by a pair: its binary name (§4.2.1) and its defining class loader.


A special case are classes created via the new defineHiddenClass method. Since those classes can not get resolved through their defining loader by name, it’s possible to unload a hidden class as soon as no reference to it exists. It can’t get reloaded again. But you could use the same definition to create an arbitrary number of identical hidden classes, as they do not interfere.

Holger
  • 285,553
  • 42
  • 434
  • 765
  • Great, this elaborated answer and your first comment, perfectly addresses all my question marks which I had put into question. Thanks a lot. – MyWay Dec 11 '20 at 10:02
0

Have you tried creating a persistant object using the singleton design pattern?

A singleton is a class of object that is unique across the application, which is created when instantiated for the first time.

A singleton exists as long as the application is running and any instantiation returns the current instance or a new instance if it hasn't been instantiated before. If you want a new instance you could implement a method on the singleton class that destroys the current instance and returns a new one. I use singletons to store settings and for access and credentials management.

Here's the link to a post about singletons: Singleton Design Pattern

If you don't run multiple threads you could use the method 1 described in the post, which is what i regularly do. However, if you run multiple threads i would suggest using the last method mentioned in the post, as it claims to be the best, though i haven't test it.