How to remove module layer in Java 9?

Viewed 984

I have three modules: module-a, module-b, module-c. Module-a and module-b are in boot layer. Layer for module-c I create myself. Module-c has JPMS implementation of the service which interface is in module-a.

This is the way I create layer with module-c in module-b.

ModuleFinder finder = ModuleFinder.of(moduleCPath);
ModuleLayer parent = ModuleLayer.boot();
Configuration cf = parent.configuration().resolve(finder, ModuleFinder.of(), Set.of("module-c"));
ClassLoader scl = ClassLoader.getSystemClassLoader();
ModuleLayer layer = parent.defineModulesWithOneLoader(cf, scl);

Then in module-b I call service from module-c. After service execution completed I don't need module-c and new created layer any more. How to remove it from JVM and release all resources? Is it enough to do layer = null;?

2 Answers

The module layer, the modules in the layer, and class loaders supporting the layer, are eligible to be GC'ed/unloaded when they are no longer reachable.

If you want to prove this to yourself then create a weak reference to the layer object and you should see that the reference is cleared (and queued if you are using a reference queue) when the layer is GC'ed.

An EMPTY_LAYER shall solve your use-case(from one of the comments on the question, trying to assign new HashSet<> as roots) here, wherein the references to other layers no more handled within the layer that you created :

layer = ModuleLayer.empty();

Returns the empty layer. There are no modules in the empty layer. It has no parents.


On the thought of being able to remove a layer explicitly form the JVM, I would not probably expect such an API exposed publicly since a JVM is supposed to have at least one non-empty layer, the boot layer, that is created when the Java virtual machine is started.

And if such a method is exposed, I wonder if users can try and remove this layer as well. Though I am trying to be technically hypothetical on this part.

Related