AbstractFacade and weak references

21 views
Skip to first unread message

Antoine Mischler

unread,
Nov 20, 2014, 5:57:52 AM11/20/14
to jrebirt...@googlegroups.com
Hi,

I'm wondering why the AbstractFacade is using WeakReference as values for its component map.

I unterstand that the map is a WeakHashMap, so that a component can be released if its unique key is not referenced anymore.
However, I don't understand why the values are wrapped into weakreferences.

For example a Model can be released even if it's unique key is still referenced. In this case, it's impossible to remove the Node of this Model from the view, since retrieving the Model from the facade will generate a new instance.

I'm I missing something? Is there another mechanism to prevent a Model whose unique key is referenced and with a Node in the scene graph from being garbage collected?

Thanks for your help,
-- 
Antoine Mischler

Sebastien Bordes

unread,
Nov 20, 2014, 8:22:00 AM11/20/14
to jrebirt...@googlegroups.com
Hi Antoine,

This map stores Component by ComponentKey

The goal is to released from this map all components that are not strongly referenced by an alive component. A alive componet is a component that hold a node displayed into the scene or a component registered to the Notifier to listen some WaveTypes

The WeakHashMap will remove the entry when the key is released, but the key is strongly referenced by the component itself (AbstractReady.key).

By using a WeakReference to wrap the Component, it allows to release the component
-> the entry will have a valid kay but a weakreference with an empty value.
-> then the key will be released by the component and the entry will be removed.

The strong reference used to retain a Component should be done on the Component itself not the key.

Views have a listener on their rootNode to detect parent removal.

        // Allow to release the model if the root business object doesn't exist anymore
        getRootNode().parentProperty().addListener(new ChangeListener<Node>() {

            @Override
            public void changed(final ObservableValue<? extends Node> observable, final Node oldValue, final Node newValue) {
                if (newValue == null) {
                    getModel().release();
                }
            }

        });

Which kind of Model do you use ? This tip is not performed for SimpleModel (it's a lack) but it's also performed for FXMLModel

Can you explain your use case because I don't understand what you are trying to do ?

Seb

Antoine Mischler

unread,
Nov 20, 2014, 11:38:23 AM11/20/14
to jrebirt...@googlegroups.com
Hi Sebastien,

Thanks for your answer. I'm using a custom Model implementation to use views from a previous project in a JRebirth application.
My custom Model implementation extends AbstractBaseModel. It looks like registering the SHOW_VIEW and HIDE_VIEW are not done in this base implementation. That explains why my model was released even if it's Node was still in the scene graph. Registering these wave types during model initialization fixes my issue.

Why not pushing up the registration to the SHOW_VIEW and HIDE_VIEW waves from the AbstractModel to the AbstractBaseModel?

I have also added a listener to the parent node to release the model as you suggest. This sets the model key to null when the node is removed from the scene.
However it looks like this model instance is still retrieved by the facade when using the retrieve method. Should something else be done to ensure that a released model is removed from the facade? (note: I'm using JRebirth 7.7.0)

Sebastien Bordes

unread,
Nov 20, 2014, 12:03:41 PM11/20/14
to jrebirt...@googlegroups.com
In 7.7.0 if WaveTypes are listened so a strong reference is hold by Notifier that void GC to get your Model.
 
Why not pushing up the registration to the SHOW_VIEW and HIDE_VIEW waves from the AbstractModel to the AbstractBaseModel?
Because in some cases we can want to listen these WaveType (so we can extend AbstractModel) and sometimes not (we can extends directly AbstractBaseModel)
So you can choose to extend AbstractModel instead of the base one.


However it looks like this model instance is still retrieved by the facade when using the retrieve method. Should something else be done to ensure that a released model is removed from the facade? (note: I'm using JRebirth 7.7.0)

Can you check that the release method is called for this model (override it and put a breakpoint). you should also be sure that your Model doesn't listen any WaveType, you can unregister them into the release method ! (it's done automatically into 7.7.5)
Otherwise get YourKit and search who is strongly referencing your model that avoid it to be removed from the facade.

All things related to Components' releasing have been fixed into 7.7.5, so you should plan to migrate, a lot of bug fixes have been done.

Let me know if you need more help.

Seb
 
Reply all
Reply to author
Forward
0 new messages