Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-8093223

asObject() bindings always get Garbage Collected

    XMLWordPrintable

Details

    • Bug
    • Resolution: Not an Issue
    • P3
    • 8u40
    • 8u20
    • javafx
    • Windows 7 - latest patches

    Description

      asObject() bindings get Garbage Collected - but they should hold a reference to the binding they were asObject()'ed of or some other hard reference as otherwise they can't be used in MVC setups.

      This is related to https://javafx-jira.kenai.com/browse/RT-37721 - which was closed with "not an issue". As I cannot reopen that, I created this issue.

      I do believe this is a proper issue as we cannot find a "pretty" workaround for it outside of creating our own asObject() implementation that uses listeners to update both ends of the bindings being bound bidirectionally as currently asObject() gets nearly instantly Garbage Collected.

      The issue seems to lie in the fact that a binding (let's use a LongBinding to have an example) that gets bidirectionally bound to an ObjectProperty<Long> via an asObject() call - has no hard reference to the previous binding or the bean it belongs to, so by itself it's "weak" and is nearly instantly collected by the Garbage Collector unless a hard reference for it is kept in active code, which is pretty much not possible in a MVC setup as by the time the controller has been created and "used" it's assumed to be "end of life" in terms of the GC.

      Looking at asObject() for LongProperty (all property implementations look basically the same for the primitive types) there's this code:

        @Override
          public ObjectProperty<Long> asObject() {
              return new ObjectPropertyBase<Long> () {
                  {
                      BidirectionalBinding.bindNumber(this, LongProperty.this);
                  }

                  @Override
                  public Object getBean() {
                      return null; // Virtual property, does not exist on a bean
                  }

                  @Override
                  public String getName() {
                      return LongProperty.this.getName();
                  }

                  @Override
                  protected void finalize() throws Throwable {
                      try {
                          BidirectionalBinding.unbindNumber(this, LongProperty.this);
                      } finally {
                          super.finalize();
                      }
                  }

              };
          }


      It's clear it has no bean reference, so that reference is already gone, and in the bindNumber() method there's weak references created (in TypedNumberBidirectionalBinding) that are then used as a values for the addListener() call for each property that is being bound.

      It seems to me this is all so "weakly referenced" that if you try to bind anything using asObject() and cannot keep a hard reference in actively executed code, that binding will be GC'd at some near-instant point in time. Keeping it "active" may be possible outside of loading controllers but if you use a typical MVC setup where the controller is bound to the GUI Controls, and use asObject() - it becomes completely unusable as the Garbage Collector sees no reference to the GUI control it's bound to (as it has seemingly no reference to the binding it was created from) and gets destroyed nearly instantly, which then means the bindings no longer work.

      Logically the hard reference would be
      GUIController->ValueBinding->asObjectBinding

      The first two are "hard" but the last step is "weak"

      I can't see why the asObject() binding that's created doesn't at least have a hard reference to what binding it was created from, so that it's not garbage collected until the previous binding is. Perhaps there's some logic I don't see, but as it currently stands, asObject() bindings cannot be used in a MVC setup.

      Hope I wasn't too unclear, it's a little hard to explain in text.

      Attachments

        Issue Links

          Activity

            People

              msladecek Martin Sládeček
              ecrumhornjfx Emil Crumhorn (Inactive)
              Votes:
              0 Vote for this issue
              Watchers:
              4 Start watching this issue

              Dates

                Created:
                Updated:
                Resolved:
                Imported: