views:

130

answers:

4

Hello,

my application (ASP.NET MVC) shows a page which loads data constantly, at certain intervals.
The jQuery script calls a controller and this one renders a different partial view, based on certain conditions.
This partial view is the appended to the DOM with jQuery; previous elements are removed with the empty() method.

        $(document).ready(function() {
        var ScheduledAction = function(func, times, interval) {
            var ID = window.setInterval(function(times) {
                return function() {
                    if (times > -1) {
                        if (--times <= 0) 
                            window.clearInterval(ID);
                        }
                    func();
                }
            } (times), interval);
        };
        ScheduledAction(function() {
            LoadAppointments();
            }, -1, <%=Model.RefreshTimeout %>);
    });

    function LoadAppointments()    {

        $("#AppointmentsList").empty();
        $('#loading').html("<img src='Images/bigloader.gif' />");
        $.get(UrlAction, 
            function(data) {
                if (data != '') {
                    $('#AppointmentsList').append(data);
                    $('#loading').empty();
                   } 
                else {
                    $('#loading').fadeOut(3000, function() { $('#loading').empty(); });
                   }
            });
        }  

The controller (UrlAction) returns a partial view. For Each roundtrip the partial view is different. Once the partial view contains just an image. In the other situation is a div with some infos.

I've realized that after one day the browser loads something like 600Mb of memory. What am I doing wrong?

Thanks

Alberto

+1  A: 

I believe it's not you being wrong, but rather it is the implementation of JavaScript in the browser. Do you face this problem in different browsers (Firefox, Opera, Internet Explorer), or only in some specific browser?

To get a better answer, you should post some of the JavaScript code that renders your page - maybe there are some optimizations possible.

naivists
I've updated with some code.The problem is with IE8.I've tried with other browsers and things seem better but I have to use IE.Thanks
vandalo
A: 

You can check if DOM is leaking with Drip tool (article) As a temporary workaround may be you should completely reload the whole page periodically.

Andrew Florko
I am going to read the article, thanks.What I am doing now is every 500 roundtrips there will be a reload.
vandalo
Hope it helps )
Andrew Florko
A: 

You might want to try this instead:

[EDIT] removed function being returned to setInterval

$(document).ready(function() {
    $('#loading').html("<img src='Images/bigloader.gif' />").hide();
    ScheduledAction(LoadAppointments, -1, <%=Model.RefreshTimeout %>);
});

function ScheduledAction(func, times, interval) {
    var ID = window.setInterval(function() {
        if (times > -1) {
            if (--times <= 0)
                window.clearInterval(ID);
        }
        func();
    }, interval);
}

function LoadAppointments() {

    $("#AppointmentsList").empty();
    $('#loading').show();
    $.get(UrlAction,
            function(data) {
                if (data != '') {
                    $('#AppointmentsList').append(data);
                    $('#loading').hide();
                }
                else {
                    $('#loading').fadeOut(3000);
                }
            });
}

I noticed that you were loading your spinner every time you were loading appointments. Also you were passing in times into the window.setInterval.

My code testing this function is:

$(document).ready(function() {
    $('#loading').html("<img src='loader64.gif' />").hide();
    ScheduledAction(LoadAppointments, 1, 100);
});

function ScheduledAction(func, times, interval) {
    var ID = setInterval(function() {
        if (times > -1) {
            if (--times <= 0)
                clearInterval(ID);
        }
        func();
    }, interval);
}

function LoadAppointments() {

    $("#content").empty();
    $('#loading').show();
    $.get('contentServer.php',
            function(data) {
                if (data != '') {
                    $('#content').append(data);
                    $('#loading').hide();
                }
                else {
                    $('#loading').fadeOut(3000);
                }
            });
}

The php file:

//contentServer.php

<?php

echo 'The quick brown fox jumped over the lazy dogs back';

?>
Gutzofter
Thanks for your help Gutzofter but this script doesn't work. LoadAppointments is never called. Alberto
vandalo
Edited code. The function that you wanted executed by set interval actual returned another function. No execution.
Gutzofter
I think that this may be the cause of your memory leak. Every time an interval was executed it generated a new function then executed it.
Gutzofter
Thanks Gutzofter but, again, I think your code doesn't work. Did you try it? It's only fired the first time. I've tried to disable the cache $.ajaxSetup({ // Disable caching of AJAX responses */ cache: false }); but still it doesn't do what it should do.Alberto
vandalo
Thanks Gutzofter, I was wrong cause I forgot to set the times value. I'll give it a go and tell you what happens. Alberto
vandalo
Gutzofter your script works great (sorry for my mistakes before) but the problem is still there. Memory grows constantly. I've tried different solutions found in forums but none of them seems to work. I guess jQuery cannot destroy things properly.Alberto
vandalo
+2  A: 

It could just be a bug in jQuery?

I've run into similar issues, mostly when doing tons of AJAX requests over time, in all versions of IE.

This bug describes the problem and a simple patch to jQuery that should fix it:

http://dev.jquery.com/ticket/6242

Ryley