* Модуль реализации не собирает мусор после разыменования в модуле пользовательского интерфейса. Я переопределил метод финализации во всех классах реализации. метод finalize ни одного из объектов, вызываемых после разыменования. При выполнении разыменования в модуле реализации не выполняется поток.
Приведенный ниже код предназначен только для представления перспективы проекта. Набор WeakReferences в BankConfig, Main class не является частью исходного проекта. CoreConfig и CoreController относятся к модулю реализации. *
public class BankConfig {
public final String uuid = UUID.randomUUID().toString();
public final String name;
public Controller controller;
public BankConfig(String name, Controller controller) {
this.name = name;
this.controller = controller;
}
@SuppressWarnings("deprecation")
@Override
protected void finalize() throws Throwable {
System.out.println("garbage collected : "+uuid);
super.finalize();
}
@Override
public String toString() {
return "bank-"+uuid;
}
}
public interface Controller {
public abstract BankConfig getBankConfig();
}
public class CoreConfig extends BankConfig {
public CoreConfig(String name,Controller controller) {
super(name, controller);
}
public CoreConfig(BankConfig bankConfig) {
super(bankConfig.name, bankConfig.controller);
}
public CoreConfig(BankConfig bankConfig, final Controller controller) {
super(bankConfig.name, controller);
}
@Override
public String toString() {
return "core-"+uuid;
}
}
public class CoreController implements Controller {
public final CoreConfig config;
public CoreController(BankConfig config) {
this.config = new CoreConfig(config, this);
}
@Override
public BankConfig getBankConfig() {
return config;
}
}
public class Main {
private static final Set<WeakReference<BankConfig>> WEAK_REFERENCES = new HashSet<>();
public static final ObservableList<BankConfig> banks = FXCollections.observableArrayList();
static {
banks.add(readConfigFromDatabase("krishna"));
banks.add(readConfigFromDatabase("shankar"));
}
public static void main(String[] args) throws InterruptedException {
banks.add(loadController(readConfigFromDatabase("krishna")).getBankConfig());
banks.add(loadController(readConfigFromDatabase("shankar")).getBankConfig());
for (BankConfig bankConfig : banks) {
WEAK_REFERENCES.add(new WeakReference<BankConfig>(bankConfig));
}
banks.clear();
for (int i = 0; i < 5; i++) {
System.out.println("strong references : "+banks);
System.out.println("weak references : "+WEAK_REFERENCES.stream().filter(ref -> ref.get() != null).map(ref -> ref.get()).collect(Collectors.toSet()));
System.gc();
Thread.sleep(5000);
}
}
public static final Controller loadController(final BankConfig config) {
try {
final List<String> moduleNames = List.of("implementation");
final URLClassLoader loader = new URLClassLoader(new URL[0]);
final Configuration configuration = ModuleLayer.boot().configuration().resolveAndBind(ModuleFinder.of(Path.of(new URL("path to implementation jar").toURI())), ModuleFinder.of(), moduleNames);
final ModuleLayer moduleLayer = ModuleLayer.boot().defineModulesWithOneLoader(configuration, loader);
final Optional<Module> module = moduleLayer.findModule("implementation");
final Class<?> controllerClass = module.get().getClassLoader().loadClass("implementation.CoreController");
final Controller controller = (Controller) controllerClass.getConstructors()[0].newInstance(config);
return controller;
} catch (Exception e) {e.printStackTrace();}
return null;
}
public static BankConfig readConfigFromDatabase(final String name) {
if("krishna".equals(name)) return new BankConfig("krishna", null);
else if("shankar".equals(name)) return new BankConfig("shankar", null);
return null;
}
}