-
Notifications
You must be signed in to change notification settings - Fork 104
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Trouble with garbage collection on ComboBox #594
Comments
Hi, So what's the problem? When JavaFX loads an FXML file it looks at the controller class, injects all components and executes the initialize method. From the perspective of the FXMLoader the job of the controller class is done at this point. It doesn't hold any references to the controller instance. All that is there are at runtime are the instances of the UI components. The garbage collector will not collect ui components. If a ui component keeps a reference to the controller class then also the controller class won't be collected. But if this is not the case, then the controller class is free for collection. So when does a ui component holds a reference to the controller class? One way is to add a listener. A listener is an inner class and inner classes in java have references to their parent class. However, bindings in JavaFX are using weak references internally so no reference to the parent class is created. So how to solve this? Adding useless listeners of cause would be a solution but this is not really clean.
Example (java code not kotlin): class MyView implements FxmlView<MyViewModel> {
@FXML
private Parent rootNode;
public void initialize() {
rootNode.setUserData(this);
}
} "user-data" is there to store arbitrary data and I think this is a good use-case. The This should solve the problem as now the view instance won't be garbage collected and as the view has a reference to the viewModel, the viewModel won't be collected too. |
Hi @lestard thanks for your in-depth explanation. I was afraid it might be something very complex and not too easy to fix. I think adding the view as userdata is not very intuitive and I would have to remember doing this for most of the views. Then when I'll look at my code in a couple of years (or even months) I might wonder why the hell I did that. With the interface GarbageCollectionSafeView extends SceneLifecycle {
// default implementations of the two lifecycle methods
} simply leave a comment in there referring to this issue and know right away why I did that. Do you see any drawbacks with just implementing |
I don't see any drawbacks from using But to be honest, I don't have much experience or feedback from other users for this usage scenario as the Besides that, there shouldn't be any other drawbacks from using the |
Hi there,
I think I'm having trouble with fields being garbage collected although they are still in use. Maybe I'm just misusing Mvvmfx.
I have a ComboBox, and two Datepicker fields in my Fxml View. The ComboBox contains date presets, so when the user selects one of the presets, the date fields should change accordingly.
This view is included in a main view via
<fx:include />
Here is the CodeBehind
And here is the ViewModel
Now, when I change the ComboBox selected Item, my Log Statements in the ViewModel don't fire, so the Listener does not seem to be invoked. I traced it down to some WeakReference that seems to be garbage collected.
I tried to debug it by having the ViewModel inherit from SceneLifecycle and thought i would see the View being removed but it does not. But it was not removed but I noticed, that all of a sudden my Listener gets invoked.
Do you have any hints what I'm doing wrong?
Thanks in advance
The text was updated successfully, but these errors were encountered: