Announcement

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

    I find Memory Leakage in client Firefox when use ValuesManager

    SmartGWT Power Edition version

    I have developed an application and use Firefox. And per checking vs about:memory and find the memory usage of that URL accumulate continues from 27M to over 200M until the application halt and no response after clicking several record and loaded data from server to client.

    I have already narrowed down the issue as following

    I have a search form that get the list grid, when double click the record on the search result listgrid, it will open/refocus a Tab.
    Inside the Tab, I use ValuesManager with add ~ 7-8 DynamicForms and ~ 100 fields, several ListGrid for child object. And when click the record in the result list grid, it will call editRecord and display the data onto the ValuesManager of the Tab.

    And When I click the first record in result list grid, the memory usage go from 27 to 40 and after some callback complete, it get back to 37,... and to continue click other, it continue to increase until it go to ~ 200M or 300M (in about:memory), the application become slow response and cannot proceed any more, we need to close the browser and start the Firefox again.
    We have tried closing the Tab but the memory not release in client side


    So I suspect that there is some memory leakage when I use ValuesManager as well as to call editRecord() for multiple records loading. So I want to check is there any possible,
    1. how can I check out the association that cannot detact after destroy?
    2. how to force clear up or destroy the ValuesManager so that I can release the objects... and free up the memory?

    #2
    Please let us know your exact SmartGWT and browser versions - we always need to know this.

    Note that a rising memory profile is not evidence of a memory leak - it might just mean that the system has plenty of free memory, and the actual problem where the app stops responding is something completely unrelated. To prove a memory leak, you need to starve the system of memory, to force the browser to reclaim unused memory. Alternatively, Firefox's about:memory screen has options to manually run GC, and to minimize memory usage - if you have used those options and the memory usage remains high, that would be a stronger indication that you have a real leak.

    Comment


      #3
      SmartGWT version: SmartClient Version: v9.1p_2014-03-04/PowerEdition Deployment (built 2014-03-04)
      Browser: FireFox ESR 24.3.0, with FireBug installed

      I use about:memory in FireFox and check the memory usage under my URL (e.g. http://127.0.0.1:8080/app/)

      Application Logic
      1. click the result ListGrid, we will
      2. open a Tab in SmartGWT TabSet
      3. inside the Tab have a ValuesManager to contain several DynamicForms
      4. Create a DataSource and fetchData from server side to client
      5. set ValuesManager.editRecord in order to push the fetched record to the VLayout that contain ValuesManager
      6. when user click another record in the result list, we will invalidateCache for the DataSource in order to clean the client cache, and finally force destroy the DataSource, ValuesManager as well as VLayout and setPane again the existing Tab and load another record.

      Testing Steps:
      1. before start the click of result record, I click GC button in about:memory for several times until the memory for http://127.0.0.1:8080/app/ stable and unchange
      2. click several records one by one
      3. click GC button for several times again until memory stable and unchange. Check and find more memory used. (~ 10M of memory is used after each record
      4. I repeat step 2 - 3 again and again and find the memory keep going up even I click the GC button (as well as CC button...)

      So I want to ask
      1. is there any tools in SmartGWT that I can find, from Tab that any objects that is accumulated?
      2. Any methodology we can troubleshoot the memory leakage of SmartGWT client code? (especially we only use FireFox in our company...)
      3. From the Application Logic, any missing piece that would possibly cause memory leakage? Do we have some API in SmartGWT that can help to find or dump the leakage object...

      Best Regards

      Comment


        #4
        You can use the Developer Console in a couple of ways to find leaks of components:

        1. a "Canvas count" is displayed in the Results tab - if this keeps going up, you are leaking components

        2. the "Watch Tab" shows all currently existing components. If new components keep appearing here as you repeat the cycle of your code, you are leaking components

        In addition, you can use isc.getKeys(window) to see all the global variables in your application - if on repeating runs you see the total number of variables rising here, take a look at the newly appearing entries.

        As far as your basic usage pattern - it's very strange to create a new DataSource each time you need to fetch data and you probably should not be doing that. However we attempted an internal test that behaves as you describe, and there was no leak.

        A couple of other basic items:

        1. you should update to the latest patched build

        2. you should test in any other browser and let us know whether you still see a leak

        3. you need to test in Firefox with Firebug disabled and see if you can create a leak. Firebug is known to leak memory when various tools are active.

        Comment


          #5
          Note on the point about testing with other browsers - even though you don't use other browsers normally, the point here is to confirm whether this is an application-level link (some code is holding onto memory that can't be GC'd) or a Firefox-specific browser bug (the browser itself leaks memory even though the application is correctly releasing objects).

          Finally, if you have any other extensions installed in your Firefox, please disable them and confirm the leak still occurs.

          Comment


            #6
            Thx for you reply and we working on the Canvas count as you suggested

            But as you mentioned in "isc.getKeys(window)"

            I try to write a native javascript code fragment

            Code:
            private native String [] getGlobalVariables() /*-{
            	var keys = isc.getKeys ( window );
            	return keys;
            }-*/;
            ...
            
            String [] keys = getGlobalVariables();
            for ( String key : keys  ) {
            	SC.logInfo(key);
            }
            But from DevConsole Console, I find the error

            Code:
            11:23:23.577:KPR6:INFO:Log:Exception caught: (ReferenceError) 
             stack: $getGlobalVariables@http://127.0.0.1:8080/myapp/myweb/922EEAFD4F0951CE307C8B91D9469D8B.cache.html:3913
            execute_10@http://127.0.0.1:8080/myapp/myweb/922EEAFD4F0951CE307C8B91D9469D8B.cache.html:7749
            registerKey/<@http://127.0.0.1:8080/myapp/myweb/922EEAFD4F0951CE307C8B91D9469D8B.cache.html:24735
            apply@http://127.0.0.1:8080/myapp/myweb/922EEAFD4F0951CE307C8B91D9469D8B.cache.html:233
            entry0@http://127.0.0.1:8080/myapp/myweb/922EEAFD4F0951CE307C8B91D9469D8B.cache.html:271
            entry_0/<@http://127.0.0.1:8080/myapp/myweb/922EEAFD4F0951CE307C8B91D9469D8B.cache.html:256
            isc_c_Page_handleKeyPress@http://127.0.0.1:8080/myapp/myweb/sc/modules/ISC_Core.js:1147
            isc_c_EventHandler_handleKeyPress@http://127.0.0.1:8080/myapp/myweb/sc/modules/ISC_Core.js:1182
            isc_c_EventHandler__handleNativeKeyPress@http://127.0.0.1:8080/myapp/myweb/sc/modules/ISC_Core.js:1177
            isc_c_EventHandler_dispatch@http://127.0.0.1:8080/myapp/myweb/sc/modules/ISC_Core.js:1448
            anonymous@http://127.0.0.1:8080/myapp/myweb/sc/modules/ISC_Core.js:71
            
             fileName: http://127.0.0.1:8080/myapp/myweb/922EEAFD4F0951CE307C8B91D9469D8B.cache.html
             lineNumber: 3913
             columnNumber: 0: isc is not defined
            Do you know any clue?

            Comment


              #7
              In GWT JSNI methods, you must use "$wnd" to refer to the "window" object - see the JSNI basics doc. The second line of your JSNI method should read:
              Code:
              	var keys = [b]$wnd[/b].isc.getKeys ( [b]$wnd[/b] );

              Comment


                #8
                Originally posted by Isomorphic View Post
                You can use the Developer Console in a couple of ways to find leaks of components:

                1. a "Canvas count" is displayed in the Results tab - if this keeps going up, you are leaking components

                2. the "Watch Tab" shows all currently existing components. If new components keep appearing here as you repeat the cycle of your code, you are leaking components

                In addition, you can use isc.getKeys(window) to see all the global variables in your application - if on repeating runs you see the total number of variables rising here, take a look at the newly appearing entries.
                This is very important information. Shouldn't this be in the FAQs?

                Comment


                  #9
                  First, per check with Canvas count and Watch Tab, we can identify some leakage object suchas list grid and VLayout. But when we try some form submit for updating data to DB, we find leakage of ValuesManager

                  As show below that the isc_ValuesManager_3, isc_ValuesManager_15 should be the valuesManager that we created in previous form submit.

                  So I want to ask,
                  1. is there any propor way to identify the memory leakage for DataSource, DynamicForm and ValuesManager?
                  2. what the recommended method to destroy DataSource, DynamicForm and/or ValuesManager in order to prevent such leakage?

                  Code:
                  17:59:36.718:MUP8:WARN:validation:isc_ValuesManager_3:Validation failed with the following errors:
                  ismShtNm:- Field is required
                  ismSttsIdr:- Field is required
                  ismLngNm:- Field is required
                  ismMnm:- Field is required
                  issrShtNm:- Field is required
                  issrLngNm:- Field is required
                  ismShtDscn:- Field is required
                  cnMktCod:- Field is required
                  prcInpCat:- Field is required
                  prcPrntFmt:- Field is required
                  qtnBass:- Field is required
                  17:59:36.770:MUP8:WARN:validation:isc_ValuesManager_15:Validation failed with the following errors:
                  ismShtNm:- Field is required
                  ismSttsIdr:- Field is required
                  ismLngNm:- Field is required
                  ismMnm:- Field is required
                  issrShtNm:- Field is required
                  issrLngNm:- Field is required
                  ismShtDscn:- Field is required
                  cnMktCod:- Field is required
                  prcInpCat:- Field is required
                  prcPrntFmt:- Field is required
                  qtnBass:- Field is required

                  Comment


                    #10
                    @edulid: the Canvas count and Watch Tab features are actually covered in the QuickStart Guide. It's true that the isc.getKeys() trick might deserve more attention.

                    @wing.t.lee:

                    2. what the recommended method to destroy DataSource, DynamicForm and/or ValuesManager in order to prevent such leakage?
                    Call destroy() on them.

                    1. is there any propor way to identify the memory leakage for DataSource, DynamicForm and ValuesManager?
                    Unfortunately, this question is tantamount to saying "how do I identify bugs in my code"? You need to look at when and where your code creates these components and make sure that you destroy() them if you no longer need them.

                    If you need help doing this, consider our hourly services, since it does not appear you have found any framework issue that we can address from a Support perspective.

                    Comment


                      #11
                      Originally posted by Isomorphic View Post

                      and make sure that you destroy() them if you no longer need them.
                      Is it enough to call markForDestroy() on the Window these components are created in?

                      Comment


                        #12
                        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.

                        Comment


                          #13
                          Good to know, I think I have to take a look at my ValuesManagers.
                          If I create my client-side datasources by DataSource.get("dsName").fetch( ... ) I don't need to destroy them, right?

                          Comment


                            #14
                            I assume the same goes for ResultSets? Thank you for starting this thread, this is good information.

                            Comment


                              #15
                              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.

                              ResultSets and ResultTrees also need to be destroy()ed, but only manually created ones. The ResultSet and ResultTree instances automatically created by ListGrid/TreeGrid.fetchData() are automatically destroyed with the component, and also automatically destroyed if you call setData() to replace them with your own data set.

                              Comment

                              Working...
                              X