DWR

Reverse AJAX - Browser JavaScript Memory Leak

Details

  • Type: Bug Bug
  • Status: Resolved Resolved
  • Priority: Major Major
  • Resolution: Fixed
  • Affects Version/s: 2.0.2
  • Fix Version/s: 2.0.3, 3.0.M1
  • Component/s: None
  • Description:
    Hide
    DWR-Version : 2.0.2-RC3

    Using the Reverse AJAX functionality I have found a problem when pushing JavaScript back up into the browser where the browser does not clean up the objects being pushed up from DWR. The reason I am focusing on this issue is the application I am developing requires itself to stay up almost indefinitely during certain situations while supplying real-time data to people via the internet. Needless to say having even a small memory leak in the browser will eventually cripple any machine.

    Below is a detail description of how I am able to create the problem. If needed I can supply the example code for your testing as well.

    --

    I am using the ScriptBuffer to setup my JavaScript. I then cycle through the ScriptSessions and send the script. I am not defining an entirely new script just calling and existing function I have loaded in my browser with the object that needs updating.

    ScriptBuffer snippet :

    fooUpdate(foo) {

      ScriptBuffer script = new ScriptBuffer();
      script.appendScript("updateFoo(").appendData(foo).appendScript(");");

       // Push change out to clients viewing the page
      Collection<ScriptSession> sessions = new HashSet<ScriptSession>();
      sessions.addAll(sctx.getScriptSessionsByPage(pageUrl));
      System.out.println(sessions.size());

      for (ScriptSession session : sessions) {
        session.addScript(script);
      }
    }

    Once the JavaScript function has been run in the browser a small amount of memory is left in its memory space. This can be accomplished by simply running an empty method with the passed object. I notice that the DOM element count for the page does not increase, just the memory that is being used by the browser.

    From the example being called above here is the JavaScript defined that is being called:

    function updateFoo(foo) {
    }

    The memory usage is very apparent in IE7. It seems that Firefox handles the artifact much cleaner and actually regulates its memory where IE7 simply continues to add the elements to its memory set.

    I have used Firefox and IE's tools for JavaScript debugging and found that no stray objects are created. I am using Firebug on Firefox and MS Script Debugger on IE.

    Show
    DWR-Version : 2.0.2-RC3 Using the Reverse AJAX functionality I have found a problem when pushing JavaScript back up into the browser where the browser does not clean up the objects being pushed up from DWR. The reason I am focusing on this issue is the application I am developing requires itself to stay up almost indefinitely during certain situations while supplying real-time data to people via the internet. Needless to say having even a small memory leak in the browser will eventually cripple any machine. Below is a detail description of how I am able to create the problem. If needed I can supply the example code for your testing as well. -- I am using the ScriptBuffer to setup my JavaScript. I then cycle through the ScriptSessions and send the script. I am not defining an entirely new script just calling and existing function I have loaded in my browser with the object that needs updating. ScriptBuffer snippet : fooUpdate(foo) {   ScriptBuffer script = new ScriptBuffer();   script.appendScript("updateFoo(").appendData(foo).appendScript(");");    // Push change out to clients viewing the page   Collection<ScriptSession> sessions = new HashSet<ScriptSession>();   sessions.addAll(sctx.getScriptSessionsByPage(pageUrl));   System.out.println(sessions.size());   for (ScriptSession session : sessions) {     session.addScript(script);   } } Once the JavaScript function has been run in the browser a small amount of memory is left in its memory space. This can be accomplished by simply running an empty method with the passed object. I notice that the DOM element count for the page does not increase, just the memory that is being used by the browser. From the example being called above here is the JavaScript defined that is being called: function updateFoo(foo) { } The memory usage is very apparent in IE7. It seems that Firefox handles the artifact much cleaner and actually regulates its memory where IE7 simply continues to add the elements to its memory set. I have used Firefox and IE's tools for JavaScript debugging and found that no stray objects are created. I am using Firebug on Firefox and MS Script Debugger on IE.
  1. dwr-local-js.zip
    (0.7 kB)
    Thomas S. Pangborn
    23/Aug/07 3:53 PM
  2. DWR-ML.zip
    (1.86 MB)
    Thomas S. Pangborn
    23/Aug/07 3:55 PM
  3. j-jetty-dwr-comet-src.zip
    (24 kB)
    Thomas S. Pangborn
    23/Aug/07 3:56 PM

Issue Links

Activity

Hide
Thomas S. Pangborn added a comment - 21/Aug/07 3:36 PM

This problem occurs on previously release versions of DWR as well. I have tested this on 2.0.1 with the same results.

Show
Thomas S. Pangborn added a comment - 21/Aug/07 3:36 PM This problem occurs on previously release versions of DWR as well. I have tested this on 2.0.1 with the same results.
Hide
Thomas S. Pangborn added a comment - 23/Aug/07 3:53 PM

Modified HTML code that generates updates similar to the DWR server based components. This code was taken from a post from Lance of the development mailing list and modified to suit this problem.

The output on the browser does the same math to display the data only using JavaScript and not DWR.

Show
Thomas S. Pangborn added a comment - 23/Aug/07 3:53 PM Modified HTML code that generates updates similar to the DWR server based components. This code was taken from a post from Lance of the development mailing list and modified to suit this problem. The output on the browser does the same math to display the data only using JavaScript and not DWR.
Hide
Thomas S. Pangborn added a comment - 23/Aug/07 3:55 PM

This is a NetBeans project with the j-jetty-dwr-comet-src modified to use DWR 2.0.2-RC3. This runs and display similar information as the JavaScript only version with DWR except the memory leak is now present.

Show
Thomas S. Pangborn added a comment - 23/Aug/07 3:55 PM This is a NetBeans project with the j-jetty-dwr-comet-src modified to use DWR 2.0.2-RC3. This runs and display similar information as the JavaScript only version with DWR except the memory leak is now present.
Hide
Thomas S. Pangborn added a comment - 23/Aug/07 3:56 PM

This is the j-jetty-dwr-comet-src code posted by Philip with modified parts to match all examples. This running under Jetty also performs well and displays the updates via DWR, but again the memory leak is now present where the JavaScript only version on the browser does not.

Show
Thomas S. Pangborn added a comment - 23/Aug/07 3:56 PM This is the j-jetty-dwr-comet-src code posted by Philip with modified parts to match all examples. This running under Jetty also performs well and displays the updates via DWR, but again the memory leak is now present where the JavaScript only version on the browser does not.
Hide
Richard Faber added a comment - 21/Sep/07 6:14 PM

I'm not sure if its exactly the same issue, but I tested the famous Chat demo,
http://today.java.net/pub/a/today/2007/03/22/developing-applications-using-reverse-ajax.html
and "Stocks" demo, the http://upl.codeq.info/ajaxkurs/stocks.html
and both examples leaked in FireFox 2.x and IE 6 on Windows....(Firefox had no leak on Linux)
During about 20 hours IE running "Stocks" went from 20M to 144M !!! and IE6 also went from
17M to 28M in 4hours doing nothing on the "Chat" demo. and again IE6 from 18M to 130M overnight.
Also another persons XP with same IE6 found leaks... (not just my Windows XP IE6).
I would like to use DWR for a financial realtime streaming application...but cannot until this improves.
The memory leaks happen every time the 60000 ms poll occurrs. (about 400K at a time)

Show
Richard Faber added a comment - 21/Sep/07 6:14 PM I'm not sure if its exactly the same issue, but I tested the famous Chat demo, http://today.java.net/pub/a/today/2007/03/22/developing-applications-using-reverse-ajax.html and "Stocks" demo, the http://upl.codeq.info/ajaxkurs/stocks.html and both examples leaked in FireFox 2.x and IE 6 on Windows....(Firefox had no leak on Linux) During about 20 hours IE running "Stocks" went from 20M to 144M !!! and IE6 also went from 17M to 28M in 4hours doing nothing on the "Chat" demo. and again IE6 from 18M to 130M overnight. Also another persons XP with same IE6 found leaks... (not just my Windows XP IE6). I would like to use DWR for a financial realtime streaming application...but cannot until this improves. The memory leaks happen every time the 60000 ms poll occurrs. (about 400K at a time)
Hide
Richard Faber added a comment - 21/Sep/07 7:14 PM

Then I made the "Stocks" demo speed up... IE6 grew from 19M to 36M in 15 min. (DWR 2.0.1) (Windows XP)

Show
Richard Faber added a comment - 21/Sep/07 7:14 PM Then I made the "Stocks" demo speed up... IE6 grew from 19M to 36M in 15 min. (DWR 2.0.1) (Windows XP)
Hide
Richard Faber added a comment - 24/Sep/07 7:55 PM

Then tried sending less data via same "Stocks" like demo with DWR 2.0.2.rc3 and IFRAMES/EarlyClose .... same leaks (IE6 and FF)

Show
Richard Faber added a comment - 24/Sep/07 7:55 PM Then tried sending less data via same "Stocks" like demo with DWR 2.0.2.rc3 and IFRAMES/EarlyClose .... same leaks (IE6 and FF)
Hide
Mike Wilson added a comment - 22/Apr/08 9:38 AM

Mike wrote:
> The way reverse ajax polling is
> done for IE has been changed throughout the 2.0.x versions:
>
> 2.0 - 2.0.1: Iframe ("clicking sound")
> 2.0.2 RC1 - RC3: htmlfile
> 2.0.2 RC4 - 2.0.3: XHR

Ok, I've done some tests on the latest version for each poll
type. I've used the Reverse Ajax Clock example with Early
Closing Mode to work through polls at a high rate. This is what
I am getting for different versions and browsers (note that my
Safari 2 tests are not yet included in the results):

2.0.1 (IE iframe poll)
All browsers ok, except IE that doesn't seem to clean up the
iframes used for communication, although removed from DOM.
= memory leak for IE

2.0.2 RC3 (IE htmlfile poll)
IE leaks here too, but haven't done any extensive testing for
causes.
= memory leak for IE

2.0.3 (XHR poll for all)
All browsers ok.

Thus, with current version 2.0.3 I can not see any leaks in
reverse Ajax. From Thomas's bug report I can see he was using
2.0.2 RC3 at the time which correlates fine with my findings.
So, those of you that have had memory problems with reverse
Ajax, please re-test with 2.0.3.

The iframe mode is no longer used by default but may activate
in IE without ActiveX, so I will look into that problem before
closing the bug opened by Thomas.

Show
Mike Wilson added a comment - 22/Apr/08 9:38 AM Mike wrote: > The way reverse ajax polling is > done for IE has been changed throughout the 2.0.x versions: > > 2.0 - 2.0.1: Iframe ("clicking sound") > 2.0.2 RC1 - RC3: htmlfile > 2.0.2 RC4 - 2.0.3: XHR Ok, I've done some tests on the latest version for each poll type. I've used the Reverse Ajax Clock example with Early Closing Mode to work through polls at a high rate. This is what I am getting for different versions and browsers (note that my Safari 2 tests are not yet included in the results): 2.0.1 (IE iframe poll) All browsers ok, except IE that doesn't seem to clean up the iframes used for communication, although removed from DOM. = memory leak for IE 2.0.2 RC3 (IE htmlfile poll) IE leaks here too, but haven't done any extensive testing for causes. = memory leak for IE 2.0.3 (XHR poll for all) All browsers ok. Thus, with current version 2.0.3 I can not see any leaks in reverse Ajax. From Thomas's bug report I can see he was using 2.0.2 RC3 at the time which correlates fine with my findings. So, those of you that have had memory problems with reverse Ajax, please re-test with 2.0.3. The iframe mode is no longer used by default but may activate in IE without ActiveX, so I will look into that problem before closing the bug opened by Thomas.
Hide
Mike Wilson added a comment - 22/Apr/08 9:41 AM

The bug as described is already fixed so I'm closing this issue.
The remaining problem with iframe mode is moved to a separate bug report, DWR-241.

Show
Mike Wilson added a comment - 22/Apr/08 9:41 AM The bug as described is already fixed so I'm closing this issue. The remaining problem with iframe mode is moved to a separate bug report, DWR-241.
Hide
Richard Faber added a comment - 22/Apr/08 3:38 PM

Still not working when I test dwr.jar 2.0.3 with IE6 sp2.
I was testing a very active "Stocks" demo (10-20 values changing per sec)
I still get IE memory leaking...
Without maxWaitAfterWrite: 20M to 110M (1hr);
With maxWaitAfterWrite: 20M to 120M (30min);
I did a quick test....maybe I did something wrong...

My servlet web.xml with this...
<servlet>
<servlet-name>dwr-invoker</servlet-name>
<display-name>DWR Servlet</display-name>
<servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class>
<init-param> <param-name>debug</param-name> <param-value>false</param-value> </init-param>
<init-param> <param-name>activeReverseAjaxEnabled</param-name> <param-value>true</param-value> </init-param>
<init-param> <param-name>maxWaitAfterWrite</param-name> <param-value>500</param-value> </init-param>
</servlet>

FFox Firebug console entries like this with XHR debugging on.
http://faber-lws.planalytics.com/pt/dwr/call/plainpoll/ReverseAjax.dwr (avg 650ms) engine.js (line 684)

Show
Richard Faber added a comment - 22/Apr/08 3:38 PM Still not working when I test dwr.jar 2.0.3 with IE6 sp2. I was testing a very active "Stocks" demo (10-20 values changing per sec) I still get IE memory leaking... Without maxWaitAfterWrite: 20M to 110M (1hr); With maxWaitAfterWrite: 20M to 120M (30min); I did a quick test....maybe I did something wrong... My servlet web.xml with this... <servlet> <servlet-name>dwr-invoker</servlet-name> <display-name>DWR Servlet</display-name> <servlet-class>org.directwebremoting.servlet.DwrServlet</servlet-class> <init-param> <param-name>debug</param-name> <param-value>false</param-value> </init-param> <init-param> <param-name>activeReverseAjaxEnabled</param-name> <param-value>true</param-value> </init-param> <init-param> <param-name>maxWaitAfterWrite</param-name> <param-value>500</param-value> </init-param> </servlet> FFox Firebug console entries like this with XHR debugging on. http://faber-lws.planalytics.com/pt/dwr/call/plainpoll/ReverseAjax.dwr (avg 650ms) engine.js (line 684)
Hide
Mike Wilson added a comment - 22/Apr/08 10:54 PM

Richard, could you try the reverse ajax clock example? (from demo/ and web/ in the source tree or just get the WAR from https://dwr.dev.java.net/servlets/ProjectDocumentList?folderID=9081)
It refreshes the time every second so it's not as "fast" as your example, but it would give us a common reference as it is the one I have been using for reverse ajax memory tests.
Also, it would be great if you could do this with 2.0.4 RC1 (same link as above) so we know you are not affected by any other memory leaks that have now been fixed in the new version.
Thanks / Mike

Show
Mike Wilson added a comment - 22/Apr/08 10:54 PM Richard, could you try the reverse ajax clock example? (from demo/ and web/ in the source tree or just get the WAR from https://dwr.dev.java.net/servlets/ProjectDocumentList?folderID=9081) It refreshes the time every second so it's not as "fast" as your example, but it would give us a common reference as it is the one I have been using for reverse ajax memory tests. Also, it would be great if you could do this with 2.0.4 RC1 (same link as above) so we know you are not affected by any other memory leaks that have now been fixed in the new version. Thanks / Mike
Hide
Richard Faber added a comment - 28/Apr/08 3:15 PM

Seems to be working fine after more testing.

Tested with 2.0.3 for 30 minutes (so far) with no (or insignificant) memory growth!
Tested the Clock: (1 value per sec) IE6 16.75M to 16.88 M in 30minutes.
Also tested the Fast Stocks demo (10-20 values per sec) IE6 18.8M to 19.2M in 30minutes
(This is wonderful results compared to before... basically no memory leak)

Thanks for fixing this issue!!!!

Show
Richard Faber added a comment - 28/Apr/08 3:15 PM Seems to be working fine after more testing. Tested with 2.0.3 for 30 minutes (so far) with no (or insignificant) memory growth! Tested the Clock: (1 value per sec) IE6 16.75M to 16.88 M in 30minutes. Also tested the Fast Stocks demo (10-20 values per sec) IE6 18.8M to 19.2M in 30minutes (This is wonderful results compared to before... basically no memory leak) Thanks for fixing this issue!!!!
Hide
Richard Faber added a comment - 27/Aug/08 6:59 PM

I am suspicious of the return of a memory leak when doing DWR comet with javascript lazy loading.
I am running a complicated web app (financial risk management)... previously no leak with DWR comet.
Then with lazy loading... I get a leak. (I have to test more to be 100% sure)
So far in only 4 hours I have 60M in the leaky app (DWR+lazy) and 31M in the app w/o DWR reverse ajax or lazy loading.
Sorry, I need to do more testing... to confirm... I'm not 100% sure since its a complicated app.
But just curious if anyone else does javascript lazy loading with DWR reverse ajax and long running apps?

Show
Richard Faber added a comment - 27/Aug/08 6:59 PM I am suspicious of the return of a memory leak when doing DWR comet with javascript lazy loading. I am running a complicated web app (financial risk management)... previously no leak with DWR comet. Then with lazy loading... I get a leak. (I have to test more to be 100% sure) So far in only 4 hours I have 60M in the leaky app (DWR+lazy) and 31M in the app w/o DWR reverse ajax or lazy loading. Sorry, I need to do more testing... to confirm... I'm not 100% sure since its a complicated app. But just curious if anyone else does javascript lazy loading with DWR reverse ajax and long running apps?
Hide
Mike Wilson added a comment - 28/Aug/08 9:32 AM

Hi Richard,
You are probably better off asking this on the mailing list as not so many people are reading the bug reports.
For a reference test, you can run the Reverse Ajax Clock example from DWR demos in your environment, to see if it leaks.
Best regards
Mike

Show
Mike Wilson added a comment - 28/Aug/08 9:32 AM Hi Richard, You are probably better off asking this on the mailing list as not so many people are reading the bug reports. For a reference test, you can run the Reverse Ajax Clock example from DWR demos in your environment, to see if it leaks. Best regards Mike

People

Dates

  • Created:
    21/Aug/07 3:31 PM
    Updated:
    28/Aug/08 9:32 AM
    Resolved:
    22/Apr/08 9:41 AM