Details

    • Epic Link:
    • Rice Module:
      KRAD
    • KAI Review Status:
      Not Required
    • KTI Review Status:
      Not Required

      Description

      During the view lifecycle several components can get created (in particular with collections). This causes a huge component graph which causes memory and performance issues.

      Look into reducing the number of objects creating through use of flyweight pattern or other strategies.

        Attachments

          Issue Links

            Activity

            Hide
            ewestfal Eric Westfall added a comment -

            One obvious solution to this problem is to not create all of these additional objects. However, the nature of the framework requires this since components must be processed dynamically during every view render to apply things like appropriate ids, binding paths, and evaluated expressions which will likely be different for every instance of that particular component as cloned from the UIF definition.

            So, eliminating the new component instances is just really not an option.

            However, there are large portions of these component definitions which could remain static and cached and not necessarily need to be cloned. We could implement something like this with a variation of the flyweight pattern. In this case, we consider components immutable once they are loaded into the UIF (which essentially they are now, though it's not programatically enforced in any way). Then, instead of doing a full clone of the object, create a "thin" clone which has a pointer to the underlying component, but also allows for component instance specific values to be configured. In theory this could be done using proxies. However, I don't believe it will be feasible to do this with dynamic proxies in Java since they require the object being proxied has an interface on it which can be used for all external interaction. In the UIF, this is not the case as components can just be plain-old java classes which I think is appropriate.

            These leaves us with a couple of other proxying options:

            1. CGLIB - Dynamic proxies using extension
            2. Javassist - dynamic proxies using extension or direct bytecode manipulation
            3. Load or Build-Time Weaving using AspectJ

            Out of the three of these options, I'm exploring the Javassist option. The idea would be that whenever we go to "clone" a component, we instead create a proxy that wraps the immutable component underneath of it and delegates calls where needed, but stores modifications locally when they occur.

            Show
            ewestfal Eric Westfall added a comment - One obvious solution to this problem is to not create all of these additional objects. However, the nature of the framework requires this since components must be processed dynamically during every view render to apply things like appropriate ids, binding paths, and evaluated expressions which will likely be different for every instance of that particular component as cloned from the UIF definition. So, eliminating the new component instances is just really not an option. However, there are large portions of these component definitions which could remain static and cached and not necessarily need to be cloned. We could implement something like this with a variation of the flyweight pattern. In this case, we consider components immutable once they are loaded into the UIF (which essentially they are now, though it's not programatically enforced in any way). Then, instead of doing a full clone of the object, create a "thin" clone which has a pointer to the underlying component, but also allows for component instance specific values to be configured. In theory this could be done using proxies. However, I don't believe it will be feasible to do this with dynamic proxies in Java since they require the object being proxied has an interface on it which can be used for all external interaction. In the UIF, this is not the case as components can just be plain-old java classes which I think is appropriate. These leaves us with a couple of other proxying options: CGLIB - Dynamic proxies using extension Javassist - dynamic proxies using extension or direct bytecode manipulation Load or Build-Time Weaving using AspectJ Out of the three of these options, I'm exploring the Javassist option. The idea would be that whenever we go to "clone" a component, we instead create a proxy that wraps the immutable component underneath of it and delegates calls where needed, but stores modifications locally when they occur.
            Hide
            ewestfal Eric Westfall added a comment -

            Committed a change to CollectionGroupBuilder which prevents duplicate copying from happening in the buildLine method.

            Show
            ewestfal Eric Westfall added a comment - Committed a change to CollectionGroupBuilder which prevents duplicate copying from happening in the buildLine method.
            Hide
            jkneal Jerry Neal (Inactive) added a comment -

            Resolving, initial research was complete

            Show
            jkneal Jerry Neal (Inactive) added a comment - Resolving, initial research was complete

              People

              • Assignee:
                ewestfal Eric Westfall
                Reporter:
                jkneal Jerry Neal (Inactive)
              • Votes:
                0 Vote for this issue
                Watchers:
                2 Start watching this issue

                Dates

                • Created:
                  Updated:
                  Resolved: