Announcement

Collapse
No announcement yet.
X
  • Filter
  • Time
Clear All
new posts

    #16
    Per troubleshooting vs DevConsole, Tab "Watch"

    Questions:

    1. try to click the component such as VLayout, Button as well as Label, Right Click --> Destroy, I find the component immediately disable in the UI as well as the Canvas Count decreasing, but I cannot see any droping of memory (even I click the GC button in about:memory. Is it expected?

    2. How to know the memory consumption based on particular VLayout and their Members ...? Can we find this in DevConsole?

    3. as mentioned in <http://planet.openbravo.com/blog/finding-and-fixing-memory-leaks-in-a-smartclient-based-application/> that object to be associated by addChild(...) should not be auto destroy. However we find for Canvas that it only have addChild, but no addAutoChild or addMember methods, do you know how can object in Canvas can be auto destroy?

    Comment


      #17
      Hi Isomorphic,

      I think that this thread contains very valueable information regarding "how to use the framework". It would be great if you could include them in some docs (or, if they are already, link them here).

      Originally posted by Isomorphic View Post
      See docs for destroy() - it will destroy hierarchically contained components, so yes, destroying a Window destroys components contained within it.

      This would not destroy a DataSource or ValuesManager, neither of which is a visual component.
      Is there a list of classes I have to take care of?
      What about FormItems or ListGridFields (either class variables or local variables) that I create using new, but then don't use in a DynamicForm or ListGrid via setFields. Would they leak memory as well?
      Those containing classes I talk about as always subclasses of your Window, VLayout, HLayout, ListGrid, DynamicForm, etc.

      Originally posted by Isomorphic View Post
      Generally, most applications do not destroy DataSources because they create a fixed set of DataSources and keep them around for the entire user session. If you have one of the rare applications which generates a potentially unbounded set of new DataSources on the fly during a session, you do need to destroy() the ones you aren't using any more to avoid leaks.
      What do you mean by "keep them around"? This sounds to me like global variables. Can you show an example how you do that?
      Do you have a "toolbox" class instance that you pass around the whole application? Is it some singleton class?

      In my application I have e.g. a Window-subclass. Every time the window is opened with eg:
      Code:
      editItemWindow = new AddEditItem(record.getAttributeAsLong("ITEM_ID"), false, true);
      editItemWindow.show();
      it does a
      Code:
      final private DataSource someDS = DataSource.get(dsString);
      The Window is then closed by a call to destroy() (will change it to markForDestroy()).

      From this thread I get that this way I will leak a DS for every window open/close cycle.
      I'd really like to know the best practice here.


      The questions summarized are:
      • Is there a list of classes I have to take care of? Every com.smartgwt.client.*-class instance that is not used with setFields(), addMember(), setItems() etc?
      • What about unused FormItems and ListGridFields?
      • How to "keep DataSources around"? ("toolbox" class instance?, singleton class?)
      • Is there already a documentation on this?
      • If not, can you suggest a best practice here?


      I think that this information is very valuable for all users following this thread.

      Thank you & Best regards,
      Blama

      Comment


        #18
        Originally posted by Blama View Post
        I think that this thread contains very valueable information regarding "how to use the framework". It would be great if you could include them in some docs (or, if they are already, link them here).
        This is true.

        Originally posted by Blama View Post
        The questions summarized are:
        • Is there a list of classes I have to take care of? Every com.smartgwt.client.*-class instance that is not used with setFields(), addMember(), setItems() etc?
        • What about unused FormItems and ListGridFields?
        • How to "keep DataSources around"? ("toolbox" class instance?, singleton class?)
        • Is there already a documentation on this?
        • If not, can you suggest a best practice here?
        As I always use DataSource.get("ds.ds.xml") when I need a datasource operation, for example DataSource.get("ds.ds.xml").fetch(criteria); should I better use global variables instead, for example in a singleton class ?

        Comment


          #19
          Originally posted by Blama View Post
          I think that this thread contains very valueable information regarding "how to use the framework". It would be great if you could include them in some docs (or, if they are already, link them here).
          The need to destroy unused components is covered in the QuickStart Guide ("Architecture Tips"). We agree we could add additional detail in the reference area and perhaps interlink things more.


          Is there a list of classes I have to take care of?
          What about FormItems or ListGridFields (either class variables or local variables) that I create using new, but then don't use in a DynamicForm or ListGrid via setFields. Would they leak memory as well?
          This is nonsense usage (since there is no other way to use these objects), but no, those would not leak memory so long as you do not hold references to them.

          What do you mean by "keep them around"?
          This was re:DataSources. Keeping a DataSource around means just not calling destroy() on it.

          From this thread I get that this way I will leak a DS for every window open/close cycle.
          No. Using new DataSource() and assigning a DataSource ID without corresponding destroy() calls will leak DataSources if your application creates an unbounded number of DataSources. DataSource.get() will not.

          Comment


            #20
            Per further checking vs DevConsole and find the following question

            1. I cannot find the leakage due to DataSource by Dev Console? or some count (like Canvas count) can show the leakage of DataSource?

            2. I try to go to "Watch" tab in DevConsole, select an item such as ListGrid object or VLayout, right click and I find a function call "Destroy". And I try to destory the components one by one, I find that the component disappear immediately in my client browser. but I cannot see any free up of memory even I force GC in about:memory of Firefox. So my question is
            2a. is the Destory function in DevConsole same as Java API call in SmartGWT?
            2b. why I cannot see any change of memory (after GC) when I destory object by Dev Console?

            3. For short term case, is there any configure in Firefox that we can allocate more memory for DOM tree in client side?

            4. Per dumping of all object by isc.getKeys(), I find many leakage object "isc_ResultSet_XXX", by what way I can find the content of ResultSet object so that we can explicitly identify which part cause the ResultSet leakage? Can DevConsole help on this? is it reflected in canvas or some other count in the tool?
            Last edited by wing.t.lee; 3 Feb 2015, 16:47.

            Comment


              #21
              1. DataSources are not Canvases so they do not contribute to the Canvas count. The list of globals previously discussed (isc.getKeys(window)) would reveal leaked DataSources.

              2 a) yes b) as previously discussed, browsers do not immediately release memory

              3. No, and if there was, there's no reason to think it would help. Browsers do not maintain a separate, fixed-size pool for DOM objects, when they run out of memory, they have run out of all memory.

              4. When you simply toString() a ResultSet, it shows you the component that created it, if it was automatically created by a widget, such as a ListGrid. However, ResultSets are also auto-created by DataSources when using the cacheAllData or autoCacheAllData settings - are you using these settings?

              Comment


                #22
                Thx Isomorphic reply,

                and

                1. DataSources are not Canvases so they do not contribute to the Canvas count. The list of globals previously discussed (isc.getKeys(window)) would reveal leaked DataSources.
                for answer 1: we use the isc.getKeys to print out the leakage component at runtime. So I cannot place any code immediate even I find particular isc_ResultSet_XXXX. So do you know any tool in SmartGWT that can make the ResultSet visible? So that I can identify and fix the leakage quickly?

                2. I try to go to "Watch" tab in DevConsole, select an item such as ListGrid object or VLayout, right click and I find a function call "Destroy". And I try to destory the components one by one, I find that the component disappear immediately in my client browser. but I cannot see any free up of memory even I force GC in about:memory of Firefox. So my question is
                2a. is the Destory function in DevConsole same as Java API call in SmartGWT?
                2b. why I cannot see any change of memory (after GC) when I destory object by Dev Console?
                for answer 2: I have already tried to click GC in about:memory as well as to wait for over 15 minutes but still cannot get the memory free up in Firefox after I click destroy? so can I treat this as "the destroy() of object is called but the destroy action not effective and cannot free up memory after call?" Or some other reason that I can prove the object is already destroied?

                Comment


                  #23
                  If you look at any of the isc_ResultSet_XXX objects that seem to be leaked, what is the componentId listed there?

                  If it says "(cacheAllData fetch)", then that was indeed a genuine leak, and we've just fixed it for builds dated February 5 and later.

                  If not, let us know what componentIds you *do* see against those resultSet instances.

                  Comment


                    #24
                    I cannot see "(cacheAllData fetch)" when I dump the element list in SC DevConsole log.

                    Since the isc_ResultSet_XXX objects the number is dynamically assign at runtime, so I cannot match with my code. that's why I want to see whether have method to render the data at runtime...

                    Comment


                      #25
                      I try to add some SC.logInfo at destroy method for a TabSet class,

                      I find that the destroy method is called but "MySearchTabSet- destroy", but followed with the WARNmessage "Instantiating in SGWT a properties object from the SmartClient side may lead to undefined behavior if the SmartClient Framework is expecting to perform the instantiation itself."

                      And per checking with DevConsole Watch Tab, I still can see that component in the tree... Also, when I right click and destroy by DevConsole, it show the same message in the log ...

                      Do you know why I cannot destroy "MySearchTabSet" this object...


                      Code:
                      19:41:07.189:TMR9:INFO:Log:MySearchTabSet- destroy
                      19:41:07.190:TMR9:WARN:Log:Instantiating in SGWT a properties object from the SmartClient side may lead to undefined behavior if the SmartClient Framework is expecting to perform the instantiation itself.

                      Comment


                        #26
                        Originally posted by wing.t.lee View Post
                        I cannot see "(cacheAllData fetch)" when I dump the element list in SC DevConsole log.
                        Call toString() on these ResultSets to see whether (cacheAllData fetch) appears in the description.

                        Since the isc_ResultSet_XXX objects the number is dynamically assign at runtime, so I cannot match with my code. that's why I want to see whether have method to render the data at runtime...
                        We have no idea what you mean by a "method to render the data at runtime".

                        About the error message you are seeing, this generally indicates a usage error. Some possibilities:

                        1. You might be trying to call destroy() on an object which is already destroyed.

                        2. You might be calling undocumented internal methods such as BaseWidget.create() or doInit(), which would interfere with the component lifecycle - don't call undocumented methods

                        3. You might be using Component XML or a mixture of direct SmartClient JavaScript code with SmartGWT via JSNI - let us know if you are doing anything like this

                        Comment


                          #27
                          Thx again Isomorphic and the answer is very useful, per checking and I find that it would be case 1 as you mention

                          You might be trying to call destroy() on an object which is already destroyed.
                          As I find the objects is associated to two parents and when object is being by second parent, (since the first parent is already destory before) and cause error...


                          But per further checking vs Firebug on some objects isc_ValuesManager_XX and find most of the old objects in still there but value = null, I want to know whether it is waiting for GC? or not yet destroy, please see the attached image for the screen capture of firebug DOM...

                          Do you know any hint on destroy this object?
                          Also how can I check the size of object still in the DOM tree in Development Console...?
                          Attached Files

                          Comment


                            #28
                            Hi wing.t.lee,

                            Originally posted by wing.t.lee View Post
                            As I find the objects is associated to two parents and when object is being by second parent, (since the first parent is already destory before) and cause error...
                            I don't think that this is allowed. For example, if I remember correctly, it is disallowed to use a ListGridField instance in more than one ListGrid.

                            Best regards,
                            Blama

                            Comment


                              #29
                              To Blama,

                              As I find in the code (from my teammate) that they have addMember a TabSet to a Section at the beginning of the method, and than addMember the same TabSet object onto another VLayout. So when I call destroy the Section after destory of Layout, the WARNING message is occur...

                              Comment


                                #30
                                If you see a global variable with value = null, that object has been successfully destroy()d and will be garbage (unless your code holds onto another reference to it, as with any object).

                                Objects cannot be added to two parents, as Blama stated. Attempting to add the object to a new parent automatically removes it from the old.

                                You may be getting the error message you were seeing before because a widget has been destroy()d and then you try to add it to a new parent.

                                Comment

                                Working...
                                X