Сборка мусора JDK13 работает неправильно. Некоторые из объектов, на которые нет ссылок, не подлежат сборке мусора - PullRequest
0 голосов
/ 27 января 2020

Block Diagram

* Модуль реализации не собирает мусор после разыменования в модуле пользовательского интерфейса. Я переопределил метод финализации во всех классах реализации. метод 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;
    }
}

1 Ответ

0 голосов
/ 31 января 2020

Проблема была вызвана библиотекой datakernel , используемой в модуле реализации, из-за того, что JmxModule регистрировал jmx-совместимые компоненты в глобальном реестре jmx.

Ссылка: проблема datakernel # 17

...