1. #1
    Ext User
    Join Date
    Sep 2008
    Location
    USA
    Posts
    13
    Vote Rating
    0
    SeiginoRaikou is on a distinguished road

      0  

    Default [2.2] Ext.QuickTips + ASP.NET AJAX = IE Memory Leak?

    [2.2] Ext.QuickTips + ASP.NET AJAX = IE Memory Leak?


    First posted in discussion forum, though I was directed to post the issue here (if it's not a real issue feel free to remove):

    Not sure if this is a bug or not - might just be more of a compatibility issue: Use of ASP.NET AJAX and ExtJS's quick tips together seems to cause large memory problems in IE 7. I'm using ASP.NET 3.5 and ExtJS 2.2. A simple .aspx page to reproduce:

    Code:
    <%@ Page Title="" Language="C#" AutoEventWireup="false" 
      CodeFile="LeakTest.aspx.cs" Inherits="LeakTest" %>
    
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    
    <html xmlns="http://www.w3.org/1999/xhtml">
        <head id="Head1" runat="server">
            <title>Untitled Page</title>
            <link rel="stylesheet" type="text/css" href="scripts/ext/resources/css/ext-all.css" />
    
            <script type="text/javascript" src="scripts/ext/adapter/ext/ext-base.js"></script>
            <script type="text/javascript" src="scripts/ext/ext-all-debug.js"></script>
        </head>
        <body>
            <form id="mainForm" runat="server">
                <asp:ScriptManager ID="scriptManager" runat="server" />
                <script type="text/javascript">
                  Ext.onReady(function() {
                    Ext.QuickTips.init();
                  });
                </script>
            </form>
        </body>
    </html>
    Running the page in sIEve will show IE leaking ~1MB every page refresh (not "hard" leaks, but memory goes up and up without end). FF 3 seems to reclaim memory fine. Note that removing either the ScriptManager tag or the Ext.QuickTips.init statement will stop the memory issue. Any other ExtJS code besides initializing QuickTips seems irrelavant to the problem. Also, using a global function for Ext.onReady instead of an anonymous function doesn't affect the problem either.

    I traced through the Ext.QuickTips.init code (and code it calls) but couldn't find anything suspicious, maybe someone could provide some perspective on how this could occur?

  2. #2
    Ext User
    Join Date
    Sep 2008
    Location
    USA
    Posts
    13
    Vote Rating
    0
    SeiginoRaikou is on a distinguished road

      0  

    Default


    any news on this? I'll keep looking at things on my end but I'll be honest I'm kind of fumbling around in the dark here.

  3. #3
    Sencha - Community Support Team hendricd's Avatar
    Join Date
    Aug 2007
    Location
    Long Island, NY USA
    Posts
    5,962
    Vote Rating
    10
    hendricd will become famous soon enough hendricd will become famous soon enough

      0  

    Default


    Try giving Qtips a destroy method, and include it during shutdown:

    Code:
    Ext.apply(Ext.QuickTips, {
       destroy : function(){
            this.unregister();
            Ext.destroy(this.getQuickTip()); 
       }
    });
    
    Ext.EventManager.on(window,   "beforeunload",  Ext.QuickTips.destroy ,Ext.QuickTips,{single:true});
    //or equivalent
    "be dom-ready..."
    Doug Hendricks

    Maintaining ux: ManagedIFrame, MIF2 (FAQ, Wiki), ux.Media/Flash, AudioEvents, ux.Chart[Fusion,OFC,amChart], ext-basex.js/$JIT, Documentation Site.


    Got Sencha licensing questions? Find out more here.


  4. #4
    Ext User
    Join Date
    Sep 2008
    Location
    USA
    Posts
    13
    Vote Rating
    0
    SeiginoRaikou is on a distinguished road

      0  

    Default


    Unfortunately this doesn't seem to have any effect. Thanks for the reply, though - I'll keep plugging away at it to see if it's just missing something simple.

  5. #5
    Sencha - Community Support Team Condor's Avatar
    Join Date
    Mar 2007
    Location
    The Netherlands
    Posts
    24,246
    Vote Rating
    89
    Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of Condor has much to be proud of

      0  

    Default


    Ext.QuickTip extends Ext.Panel, which has a leak.
    Could you check if the patch mentioned here fixes the problem?

  6. #6
    Ext User
    Join Date
    Sep 2008
    Location
    USA
    Posts
    13
    Vote Rating
    0
    SeiginoRaikou is on a distinguished road

      0  

    Default


    I used the patched .js files referenced and it has no effect. I had high hopes but after reading the thread more carefully their problem seems different - their memory usage climbs while using panels in a no-refresh single page environment, but the memory is reclaimed after a refresh. In my case the memory doesn't seem to climb (irregularly) during usage on the page, but rather during several refreshes of the page.

    Of course they could still be related - I'll keep that in mind.

  7. #7
    Ext User
    Join Date
    Sep 2008
    Location
    USA
    Posts
    13
    Vote Rating
    0
    SeiginoRaikou is on a distinguished road

      0  

    Default


    I may have found a lead:

    First of all, the problem seems to be related to Ext.QuickTip, not any of it's parent classes, for example replacing the Ext QuickTips code shown above with:

    Code:
    var tip = new Ext.ToolTip({elements: "header,body"});
    causes the memory leak to dissapear, however

    Code:
    var tip = new Ext.QuickTip({elements: "header,body"});
    causes the memory leak to return. I traced through Ext.QuickTip some more and found what may be the problem section:

    Code:
    // private
    initComponent: function() {
        this.target = this.target || Ext.getDoc();
        this.targets = this.targets || {};
        Ext.QuickTip.superclass.initComponent.call(this);
    },
    commenting the "this.target" line will fix the problem, maybe the references between the DOM document and the quick tip is not being cleaned up? I'm not sure where the best place to call "this.target = null" would be, but I'll play with it and see if I can't prove/disprove this theory.

  8. #8
    Sencha User
    Join Date
    Apr 2012
    Location
    Austin, Texas
    Posts
    2
    Vote Rating
    0
    brian.moeskau is an unknown quantity at this point

      0  

    Default


    I have no way of reproducing the environment, so I'm not sure what to tell you. If there is a demonstrable QuickTip leak that does not rely on ASP.NET then we'll get it fixed (and there are a bunch of general leak issues fixed in SVN currently). If it really is specific to .NET, I'm not sure what we can do.

  9. #9
    Sencha User
    Join Date
    Apr 2012
    Location
    Austin, Texas
    Posts
    2
    Vote Rating
    0
    brian.moeskau is an unknown quantity at this point

      0  

    Default


    FYI, this.target is set in QuickTip for the ToolTip superclass. If you look in ToolTip, you'll see that if this.target is set it sets up event handlers, and those are later cleaned up in ToolTip.onDestroy. I would guess that if you are just reloading the page, ToolTip's onDestroy is probably not getting called correctly. I would think in that case that something like Doug's patch above would be what you need.

  10. #10
    Sencha - Community Support Team hendricd's Avatar
    Join Date
    Aug 2007
    Location
    Long Island, NY USA
    Posts
    5,962
    Vote Rating
    10
    hendricd will become famous soon enough hendricd will become famous soon enough

      0  

    Default


    @SeiginoRaikou -- Try adding in this Panel override as well. I've used it for months and cleanup much with most Panels and descendant classes (except Window).

    Code:
    Ext.override(Ext.Panel, {
       
        beforeDestroy : function(){
    
            if(this.rendered){
    
                 if(this.tools){
                    for(var k in this.tools){
                          Ext.destroy(this.tools[k]);
                    }
                 }
    
                 if(this.header && this.headerAsText){
                    var s;
                    if( s=this.header.child('span')) s.remove();
                    this.header.update('');
                 }
    
                 Ext.each(['header','topToolbar','bottomToolbar','footer','loadMask','body','bwrap'],
                    function(elName){
                      if(this[elName]){
                        if(typeof this[elName].destroy == 'function'){
                             this[elName].destroy();
                        } else { Ext.destroy(this[elName]); }
    
                        this[elName] = null;
                        delete this[elName];
                      }
                 },this);
            }
    
            Ext.Panel.superclass.beforeDestroy.call(this);
        },
        onDestroy : function(){
            //since we're doing Panel cleanup beforeDestroy instead before the elCache is destroyed
            Ext.Panel.superclass.onDestroy.call(this);
        }
    });
    "be dom-ready..."
    Doug Hendricks

    Maintaining ux: ManagedIFrame, MIF2 (FAQ, Wiki), ux.Media/Flash, AudioEvents, ux.Chart[Fusion,OFC,amChart], ext-basex.js/$JIT, Documentation Site.


    Got Sencha licensing questions? Find out more here.