簡體   English   中英

JDK13 垃圾收集無法正常工作。 一些被取消引用的對象沒有被垃圾收集

[英]JDK13 Garbage Collection Not Working Correctly. Some of the de-referenced objects not being garbage collected

框圖

*實現模塊在 UI 模塊中被取消引用后不會被垃圾回收。 我已經覆蓋了所有實現類中的 finalize 方法。 取消引用后沒有調用任何對象的 finalize 方法。 取消引用時,沒有線程在實現模塊中運行。

以下代碼僅提供項目的視角。 BankConfig 中的一組弱引用,Main 類不是原始項目的一部分。 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;
    }
}

該問題是由於 JmxModule 將與 jmx 兼容的組件注冊到全局 jmx 注冊表而導致的實現模塊中使用的數據內核庫引起的。

參考:數據內核問題 #17

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM