我的申请中有问题。任何控制器都是垃圾回收。
我准备了一个,非常简单,功能清晰,但是没有从内存中删除。
@Log4j2
public class DialogOpenProjectController extends DialogPane implements Initializable, FXMLController, FXMLPane, FXMLDialogController {
@FXML
private ObjectProperty<ResourceBundle> languageBundle = new SimpleObjectProperty<>();
@FXML
private JFXTabPane TAB_PANE_OPEN_PROJECT;
@FXML
private JFXButton BUTTON_CONFIRM;
private Tab tabOpenNewProject;
private Tab tabOpenExistingProject;
private Stage stage;
private ChangeListener<? super ResourceBundle> languageListener = this::languageChange;
private ChangeListener<? super Tab> selectedTabListener = this::selectedTabChanged;
{
tabOpenExistingProject = new Tab();
tabOpenNewProject = new Tab();
}
/**
* Initializes the controller class.
*/
@Override
public void initialize(URL url, ResourceBundle rb) {
log.trace(LogMessages.MSG_CTRL_INITIALIZATION);
this.languageBundle.setValue(rb);
initTabs();
addSelectedTabListener();
addDisableButtonListener();
addLanguageListener();
log.trace(LogMessages.MSG_CTRL_INITIALIZED);
}
@FXML
public void cancel() {
this.stage.close();
clean();
}
@FXML
public void confirm() {
if (TAB_PANE_OPEN_PROJECT.getSelectionModel().getSelectedItem().equals(tabOpenNewProject)) {
actionNewProject();
} else if (TAB_PANE_OPEN_PROJECT.getSelectionModel().getSelectedItem().equals(tabOpenExistingProject)) {
actionOpenProject();
} else {
//To to show error
}
this.stage.close();
clean();
}
private void initTabs() {
TAB_PANE_OPEN_PROJECT.getSelectionModel().select(tabOpenNewProject);
}
private void addSelectedTabListener() {
TAB_PANE_OPEN_PROJECT.getSelectionModel().selectedItemProperty().addListener(selectedTabListener);
}
private void addDisableButtonListener() {
//nothing to do temporary
}
private void clean() {
this.languageBundle.removeListener(languageListener);
languageBundle.unbind();
languageBundle.setValue(null);
TAB_PANE_OPEN_PROJECT.getSelectionModel().selectedItemProperty().removeListener(selectedTabListener);
TAB_PANE_OPEN_PROJECT.getSelectionModel().clearSelection();
TAB_PANE_OPEN_PROJECT.getTabs().clear();
BUTTON_CONFIRM.disableProperty().unbind();
selectedTabListener = null;
languageListener = null;
tabOpenNewProject = null;
tabOpenExistingProject = null;
stage = null;
getChildren().clear();
}
private void addLanguageListener() {
this.languageBundle.addListener(languageListener);
}
private void languageChange(ObservableValue<? extends ResourceBundle> observable, ResourceBundle oldValue, ResourceBundle newValue) {
reloadElements();
}
private String getValueFromKey(String key) {
return this.languageBundle.getValue().getString(key);
}
private void reloadElements() {
// Nothing to do
}
public void setStage(Stage stage) {
this.stage = stage;
}
private void selectedTabChanged(ObservableValue<? extends Tab> observable, Tab oldValue, Tab newValue) {
if (newValue.equals(tabOpenNewProject)) {
BUTTON_CONFIRM.setText(getValueFromKey(Keys.CREATE));
} else if (newValue.equals(tabOpenExistingProject)) {
BUTTON_CONFIRM.setText(getValueFromKey(Keys.OPEN));
}
}
}
为了加载FXML文件,我使用Singleton Class ScreenManager。调用此方法来加载此对话框:
public void showNewDialog(FilesFXML fxml){
FXMLLoader loader = new FXMLLoader(getClass().getResource(fxml.toString()), context.getBundleValue());
try {
Stage dialogStage = new Stage();
AnchorPane dialogwindow = (AnchorPane) loader.load();
FXMLDialogController controller = loader.getController();
dialogStage.initModality(Modality.WINDOW_MODAL);
dialogStage.initOwner(this.getStage());
Scene scene = new Scene(dialogwindow);
dialogStage.setScene(scene);
dialogStage.setResizable(false);
controller.setStage(dialogStage);
dialogStage.showAndWait();
} catch (Exception ex) {
log.error(ex.getMessage());
log.error(ex.getCause());
ex.printStackTrace();
}
}
我在VisualVM中检查了它,我看到这个控制器中的一个和2个lambdas(我想它是2个监听器的初始化)
但事件清除功能被称为此对话框仍在内存中,无法进行垃圾回收。我不知道如何强行删除它。它是真正的,因为它包含了我的所有控制器。
答案 0 :(得分:0)
我很困惑你在问什么以及你在谈论什么。然而,如果该对话框窗口是打开的,则无法对其进行垃圾回收。
为了使控制器符合垃圾收集的条件,你需要在某个地方打破这个链。
最简单的方法是关闭对话框窗口。当窗口关闭时,由于JavaFX引擎不再需要管理渲染脉冲,它将释放对该阶段的引用。那时,在那个阶段的整个事情都有资格进行垃圾收集,如果没有别的东西(它本身没有资格进行垃圾收集),那么就会有很强的参考资料。