如何在Java 9中移除模块层?

7
我有三个模块: module-a,module-b和module-c。 Module-a和module-b在引导层中。我自己创建了module-c的层。 Module-c具有服务的JPMS实现,该接口在module-a中。
这是我在module-b中创建包含module-c的层的方式。
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);

然后在模块B中,我调用了模块C的服务。当服务执行完成后,我不再需要模块C和新创建的层。如何将其从JVM中删除并释放所有资源?只做layer = null;就足够了吗?


创建一个没有 module-c 的新 ModuleLayer 无法工作吗? - Naman
请问您能否更新一下问题,说明您尝试了什么以及结果如何呢? - Naman
@nullpointer 我的问题已经包含了所有信息,我所做的事情以及问题所在。如果您有不理解的地方,请指出您不理解的内容。 - Pavel_K
你能在问题中说明一下,通过移除该模块你想要实现什么目的,比如说接下来的“layer”会被用于什么。或者说它甚至不会被使用吗? - Naman
1
@nullpointer 是的,你说得对。layer 将不再使用。我想要做的是将这个 layer 从内存中移除并释放所有资源。 - Pavel_K
2个回答

5

模块层,层中的模块以及支持该层的类加载器,在不再可达时可以被垃圾回收/卸载。

如果您想自行验证这一点,请创建一个对layer对象的弱引用,您应该会看到该引用在层被GC'ed时被清除(如果您使用引用队列,则排队)。


如果单例对象(来自模块)加载到 RAM 中,然后移除模块会发生什么?单例会立即被移除吗? - mah454

1

一个EMPTY_LAYER可以解决您的用例(来自问题的评论之一,尝试将new HashSet<>分配为根),其中对其他层的引用不再在您创建的layer中处理:

layer = ModuleLayer.empty();

返回空层。空层中没有模块,也没有父级。


在能够显式从JVM中删除一个层的想法上,我实际上不会期望有这样一个API公开暴露,因为JVM应该至少有一个非空层,即启动Java虚拟机时创建的引导层。如果公开了这样的方法,我想知道用户是否也可以尝试删除此层。虽然在技术上我对此持假设态度。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接