I am creating a JavaFx
application in which when I click on a button then it will open a table in new stage
. But my problem is that when I close the stage
of that table, memory is not getting free by the application. Is there anything wrong with javaFX? or I have to do something else?
I have tried to set everything null at the time of closing of that stage but still memory is not getting free.
Closing event on stage of table :
TableView tableView;
Stage myStage;
this.myStage.setOnCloseRequest(new EventHandler<WindowEvent>() {
@Override
public void handle(WindowEvent t) {
TableController.this.myStage.close();
tableView.getItems().clear();
tableView.getColumns().clear();
tableView = null;
TableController.this.myStage = null;
System.gc();
}
});
I have create a method called replaceScene to load scene using fxml
file for stage. It will return it's controller and set scene into the Stage.
public static Initializable replaceScene(String fXml, Stage mystage) {
InputStream in = null;
try {
FXMLLoader loader = new FXMLLoader();
in = Utility.class.getResourceAsStream(fXml);
loader.setLocation(Utility.class.getResource(fXml));
loader.setBuilderFactory(new JavaFXBuilderFactory());
AnchorPane page;
try {
page = (AnchorPane) loader.load(in);
} finally {
in.close();
}
Scene scene = new Scene(page);
mystage.setScene(scene);
return loader.getController();
} catch (Exception ex) {
return null;
}
}
I am first getting StreamObject (java.io.InputStream) for fxml file and then pass this streamObject to FxmlLoader to load the page,
in = Utility.class.getResourceAsStream(fXml);
I am getting object of sun.net.www.protocol.jar.JarURLConnection$JarURLInputStream in the in inputstream object
stop() method and terminate the JavaFX application thread. If this attribute is false, the application will continue to run normally even after the last window is closed, until the application calls exit() . The default value is true.
A Stage in JavaFX is a top-level container that hosts a Scene, which consists of visual elements. The Stage class in the javafx. stage package represents a stage in a JavaFX application. The primary stage is created by the platform and passed to the start(Stage s) method of the Application class.
In JavaFX, an application can only have one stage but that stage can have 1 or several scenes. Therefore, we can create multiple scenes for a given JavaFX application.
I was about to post a very similar question. I must confess that I'm not a software engineer by training and my app development style probably relies on some "non-nuanced" practices and styles. One thing that I love about Java is the built-in memory management. One thing I don't love about Java is the built in memory management.
In Visual Basic 6, for example, you can be assured that once an object's reference count reaches zero that it will be destroyed. Implementing modal dialog windows in Visual Basic 6 was pretty simple:
Set myForm = new frmGetClientData
Call myForm.Initialize()
myForm.show, vbModal
nResult = myForm.getResult()
myForm.Hide()
Set myForm = nothing
As soon as the reference to myForm was cleared, it would be destroyed. This was convenient since you were assured that a new form would be constructed and initialized every time.
In Java, it is very hard to work with modal dialog windows. The dialog controller object doesn't know anything about the parent controller object unless passed a reference. Similarly the parent controller object must get a reference to the dialog controller if it needs to call methods on it. The parent controller, as it is constructing a new stage must get a reference to its own stage in order to set the modality of the dialog stage to modal.
With all these references pointing back and forth, it seems to me that in Java, a modal dialog window will never be garbage collected (because the references pointing back to the parent window and controller should remain valid) ... and that each time you use FXMLLoader to build and display a dialog window, a new large object will end up in memory with a very long life span. Using modal dialog windows in Java makes you have memory leaks, it seems to me.
One solution is to go into Visual Basic mode and be assiduous about releasing references to and from dialog windows and controllers when no longer used. What a hassle. This still doesn't provide any guarantees about when the window will be destroyed.
Another solution is to create a dialog pool and build them with initialization methods that set them to a known initial state each time you need them, rather than building a new window every time you want to show the dialog window (like I would do with Visual Basic).
Does anyone have insights about this with JavaFX? I am in the process of writing a helper class to help me build and manage modal dialog windows, but it seems to me that this really shouldn't be necessary. I may be just making extra work for myself.
There is nothing special for memory management and JavaFX. GC will run if the defined memory limit is reached. It doesn't run after setting an object = null.
Even calling System.gc()
doesn't mean the GC will run. From the Javadoc:
Calling the gc method suggests that the Java Virtual Machine expend effort toward recycling unused objects in order to make the memory they currently occupy available for quick reuse.
To determine if you have a memory leak somewhere you could use VisualVM for example to see if (and why) your application gets out of memory.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With