Closed GoogleCodeExporter closed 9 years ago
I extracted a test case that has the minimum amount of code to display the
problem.
I even have included links to the AJAX server files to get the live data in the
hope
that someone will look into this.
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
<head>
<title>Flot Test Graph</title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<!--[if IE]><script language="javascript" type="text/javascript"
src="lib/excanvas.min.js"></script><![endif]-->
<script type="text/javascript" src="lib/jquery-1.3.2.min.js"></script>
<script type="text/javascript" src="lib/jquery.flot.min.js"></script>
<script type="text/javascript">
$(document).ready(function() {
var plotRendered =false;
var plotdata;
$.getJSON
('http://vbbtech.com/test/createTestChart.php','samples=700&freq=sec&',
function(json) {
plotdata = [ {yaxis :1, data: json}];
$.plot($("#flottest"), plotdata );
plotRendered = true;
});
setInterval ( function() {
if (!plotRendered) return;
$.getJSON('http://vbbtech.com/test/getLiveData.php',function
(json) {
plotdata[0].data.shift();
plotdata[0].data.push(json);
// This causes memory leak in IE
$.plot($("#flottest"), plotdata );
});
},1000);
});
</script>
</head>
<body>
<div id ="flottest" style="width:800px; height:400px"></div>
</body>
</html>
Original comment by bensprac...@gmail.com
on 4 Dec 2009 at 12:22
I found an easy workaround for the problem. Rather than call $.plot in the
timer
callback, I skip the initialization of the options, plugins and canvas and
simply
set the data, redo the grid and redraw:
$(document).ready(function() {
var plotRendered =false;
var plotdata;
var PLOT = null; // flot plot object
$.getJSON
('http://vbbtech.com/test/createTestChart.php','samples=700&freq=sec&',
function(json) {
plotdata = [ {yaxis :1, data: json}];
PLOT = $.plot($("#flottest"), plotdata );
plotRendered = true;
});
setInterval ( function() {
if (!plotRendered) return;
$.getJSON('http://vbbtech.com/test/getLiveData.php',function
(json) {
plotdata[0].data.shift();
plotdata[0].data.push(json);
// This causes memory leak in IE
//$.plot($("#flottest"), plotdata );
PLOT.setDate(plotdata);
PLOT.setupGrid();
PLOT.draw();
});
},1000);
});
Original comment by bensprac...@gmail.com
on 4 Dec 2009 at 4:01
Hi!
Thanks for the test case. I have not run it yet, but can you attach a dump of
the
JSON to the bug so it won't go away when you change the server, I probably need
a
local dump anyway because of the same origin policy (can't make Ajax requests to
other servers).
Original comment by olau%iol...@gtempaccount.com
on 7 Dec 2009 at 4:32
I attaching a file with a snapshot of data from the server, per your request.
the
problem is that the leak happens when you feed it "real time" data. You could
simulate this without the AJAX request. The data is simply time vs a floating
point
value. You can see the format in the attached file. New data samples are fed
once a
second by an Ajax call in the Timer call back, and an example of the data
returned
is "[1260189172000,4642.57]".
Original comment by bensprac...@gmail.com
on 7 Dec 2009 at 5:34
Attachments:
I'm seeing a similar if not the same problem using xajax, not using json, i
thought it was maybe xajax but the
leak around the same amount as this.
$objResponse is the xajax object returned in php.
$objResponse -> script ( 'var d2 = ' . $abandon_str . ';var d1 = ' .
$connect_str . ';
var d3 = ' . $aHold_str . '; var d4 = ' . $cHold_str . '; var d5 = ' . $cDuration_str . ';
$j.plot($j("#grafica-calls-day"),
[{ label:"Llamadas Conectadas", data: d1, bars: { show:true, align: "center", barWidth:0.8}, shadowSize:
0, stack:true},
{ label:"Llamadas Abandonadas", data: d2, bars: { show:true, align: "center", barWidth:0.8}, shadowSize:
0, stack:true},
{ label:"En Espera Abandonadas", data: d3, lines: {show:true}, yaxis:2},
{ label:"En Espera Conectadas",data: d4, lines: {show:true}, yaxis:2},
{ label:"Duracion Conectadas", data: d5, lines: {show:true}, yaxis:2}]
,{
legend: { show:true, noColumns:3, container: $j("#grafica-15min-legend") }
},
grid: { hoverable: true },
yaxis: { min: 0, tickDecimals:0 },
y2axis: { ticks:[], min: 0, tickDecimals:0 }
});');
it seems as if a new object is created everytime $j.plot gets called but never
gets released
Original comment by jsola...@gmail.com
on 9 Dec 2009 at 5:19
Forgot to add, i experience the memory leak in every browser i've tried (IE,
Firefox, Safai and Chrome)
Original comment by jsola...@gmail.com
on 9 Dec 2009 at 5:22
Hi, can you post some working sample code? I am trying to do the exact same
thing for
days but cant get my live update working?
Please? Thanks
Original comment by kerep...@gmail.com
on 16 Dec 2009 at 10:51
I am not sure what happened, but since I originally made the post, the example
which
I included seems to have stopped working under IE, but works fine still under
Firefox. Under IE the second call to $.plot is dieing within jquery. I don't
have
time to debug this issue now. I am using similar code with the workaround that
I
previously posted and it is working fine under both browsers. The code
attached to
this issue does produce "live" charts.
I am convinced that the issue has nothing to do with the $.getJSON call and is
simply that the some large object that is created within excanvas/flot is not
getting released when a new call to $.plot is made.
Original comment by bensprac...@gmail.com
on 16 Dec 2009 at 11:49
Issue 161 is probably related. There was some analysis recently on the mailing
list:
http://groups.google.com/group/flot-graphs/browse_thread/thread/bc18c8e6f3eeff97
/36d2fa6646beb229
Original comment by olau%iol...@gtempaccount.com
on 7 Apr 2010 at 4:52
Given the analysis in that thread, here's a first-pass patch at reusing the
canvas
elements when plot is called.
Original comment by ryl...@gmail.com
on 9 Apr 2010 at 7:48
Attachments:
Hmm... found a bug in my patch, although can't seem to track down the issue.
If you
select something and then replot the same graph during the plotselected event,
it seems
to redraw the selection on the new graph.
I'm not familiar enough with the selection plugin to figure this one out yet,
but I'll
be looking into it...
Original comment by ryl...@gmail.com
on 9 Apr 2010 at 10:31
I can confirm that calling setData, setupGrid and draw methods in a sequence,
instead
of $.plot is very helpful. Before, each $.plot leaked over 10MB in Chrome for
me, now
it's very minimal.
Original comment by mateusz....@gmail.com
on 12 Apr 2010 at 11:19
In response to myself, just don't do that (replotting during a plotselected
event) :)
Otherwise patch seems stable to me.
Original comment by ryl...@gmail.com
on 14 Apr 2010 at 6:32
[deleted comment]
Hello,
any solution for this issue?
I'm having the same problem here and could not solve it.
Any tips?
Thanks
Original comment by muri...@gmail.com
on 20 Sep 2010 at 12:47
First. reuse-canvas patch is working ok. I'm not sure if it fixes IE leaks, but
it significantly lowers GC pressure on all browsers. It should be merged.
Second. As a workaround for IE I'm just reloading the page after some number of
renderings. See here:
http://github.com/membase/ns_server/blob/5aa20271557ac6778e9feb83e8c8e054a8f51d6
0/deps/menelaus/priv/js/analytics.js#L107
Original comment by alkondratenko
on 18 Oct 2010 at 11:16
Hi people!
An update on this: I've just committed a patch based on issue 387 to wipe out
the excanvas state. Hopefully that will fix IE from leaking.
Now as for the reuse-canvas patch: I am not really comfortable doing a hack
like that without some proper thought. It seems it broke select-and-replot?
What if somebody fooled around with the canvas state? We need to be sure the
state is absolutely clear and that all the events are removed etc. to be able
to do that in Flot, otherwise I'm going to be spammed by people complaining
about code that used to work now failing in mysterious ways.
Also I am wondering what it buys us compared to just resetting the data with
.setData(), .setupGrid() and .draw().
Another related issue is issue 387.
Original comment by olau%iol...@gtempaccount.com
on 14 Dec 2010 at 9:12
Cool for IE. I didn't notice any difference one way or the other though...
With and without this patch I slowly leak.
I'm fine with dumping the reuse-canvas patch, its definitely hacky - although I
don't really see the difference from what you've done in r284 for excanvas :)
As for the spamming complaints, there are already lots of complaints about
leaks from calling .plot over and over. The docs suggest that you can do
setData, setupGrid, and then draw, which is great (and doesn't leak)... and
somewhat implies that it would be a good idea to do that instead of calling
plot again.
Would it be useful to have a public function like .replot or something that
packages up the setData, setupGrid, and draw functions? Might get people
thinking instead of just blindly calling plot?
Original comment by ryl...@gmail.com
on 14 Dec 2010 at 11:06
I would vote for a replot function that packs setData, setupGrid and draw. I
experienced growing memory in FF and IE (not in Chrome) when calling $.plot
every minute. It would get beyond 1Gb and then would make the browser unusable.
I ended up switching to calling the three methods, which got rid of my problem.
The memory still grows but stops at about 200Mb on my 4Gb machine and less than
150Mb on a 2Gb machine.
Having said that, there are still a few complaints (on the mailing list) that
calling the three methods doesn't completely work. One person complained about
the grid not rescaling properly and the other complained about the previous
series still showing up.
http://groups.google.com/group/flot-graphs/browse_thread/thread/965d3b556748d67a
http://groups.google.com/group/flot-graphs/browse_thread/thread/5375fdd88f99d36b
/b826499ceb75191d
Original comment by mendesj...@gmail.com
on 21 Jan 2011 at 12:18
Ryley: I agree the excanvas hack is ugly, but at least I can understand the
consequences of it. Could you try unbinding events on as suggested by George
here
http://groups.google.com/group/flot-graphs/browse_thread/thread/5375fdd88f99d36b
/b826499ceb75191d
and see if it helps your test case?
Otherwise, .replot(data) sounds fine to me. I'm not sure there were any good
reason to split it up.
Original comment by olau%iol...@gtempaccount.com
on 26 Jan 2011 at 3:45
Issue 387 has been merged into this issue.
Original comment by olau%iol...@gtempaccount.com
on 11 Mar 2011 at 4:15
There's a helpful little test case in issue 387. I'm still hoping we can get
this fixed so both $.plot and the .draw() ways of redrawing will work.
Original comment by olau%iol...@gtempaccount.com
on 11 Mar 2011 at 4:26
Issue 386 has been merged into this issue.
Original comment by olau%iol...@gtempaccount.com
on 14 Mar 2011 at 10:35
Original comment by olau%iol...@gtempaccount.com
on 14 Mar 2011 at 10:36
I spent most of yesterday and a great deal of the day today looking into this.
I think my experiences mostly reinforce what people have been saying here on
this bug and at other places. I started out with a slight modification of the
simple example from issue 387 which shouldn't bind any events.
I found out the following things:
- IE appears to have been not too eager with releasing cleaned up DOM elements
with jQuery 1.3.2, this also caused repeated calls to setupGrid() to cause
leaks. Apparently jQuery 1.5 fixes this, I don't seem to get a leak with jQuery
1.5.1, or at least it's very small. I tried running it through sIEve but sIEve
appears to be unreliable for this purpose these days, at least I couldn't get a
simple example from a jQuery bug report that sIEve claimed was leaking to
actually lose any memory over time.
It also seems the old versions of jQuery were causing IE to leaking memory in
Ajax call so if you were fetching data through Ajax, that would have been an
additional source of memory consumption.
- Chromium is losing memory fast because it's not deallocating the canvases
properly. Other Webkit browsers, at least on Linux, seem to be affected too.
There's a bug report here:
http://code.google.com/p/chromium/issues/detail?id=69784
- Firefox 3.6 appears to be doing fine, although memory is jumping up and down.
In general, it seems the browsers are a bit sluggish in releasing removed DOM
nodes. There are two sources of those in Flot, axis labels and the canvases.
However, I'm planning to land a patch for using canvas text after 0.7 which
would reduce it to the canvases.
With that in mind, and also the fact that all Flot examples are showing people
to do the $.plot thing, I'm beginning to think hard about merging the
canvas-reuse patch despite my earlier qualms. I think I can see 4 problems with
it:
1. Surviving event handlers: but the built-in plugins are all registering
events on eventHolder so the unbind in Ryley's patch should suffice.
2. Canvas size can vary over time: it turns out one can set the canvas
width/height dynamically, it's in the canvas spec.
3. Surviving canvas state: perhaps doing a .save() immediately after creating
the canvases, then do a restore() when reusing them.
4. Collisions from code still referencing the old canvas which would previously
have been whacked but is now reused, I think the plotselecting problem falls in
this category.
So of these, 4 is probably the main problem. I can't see any other way out of
it than declaring the assumption that the old canvas is still alive buggy. For
instance, in the selection event we could swap the emission of the event and
the following redraw to avoid the assumption.
I have a preliminary revamped patch that does this, I'll see if I can finish it
tomorrow and get it tested.
Original comment by olau%iol...@gtempaccount.com
on 15 Mar 2011 at 8:25
I need to correct myself here, a) the legend is also making DOM objects and b)
part of the problem in the selection plugin is that there are in fact still
stray event handlers, in this case both one on the document and one in a
setTimeout().
To solve b), the previous plot needs to know it has died. I'm currently
experimenting with introducing an internal "plotshutdown" and a shutdown hook
to enable plugins to unbind their events. Actually, I seem to have it working,
but I think I found a bug in jQuery 1.5.1 event handling which makes it leak:
http://bugs.jquery.com/ticket/8545
Gah.
Original comment by olau%iol...@gtempaccount.com
on 16 Mar 2011 at 8:32
I've committed this now. Had to drop the plotshutdown event because of the
jQuery problem, instead I attach a plot data item to the placeholder and call
.shutdown() on that.
If you find any problems with this, I'd like to hear, it's certainly possible I
goofed up somewhere. :) For the time being, however, I'm going to assume this
fixed the problems.
Thanks to everyone involved, both here, especially Ryley for the patch, and on
other bugs.
Original comment by olau%iol...@gtempaccount.com
on 17 Mar 2011 at 2:34
Holy moly! I was running into the same issue...I had several live graphs on the
same page (and was actually using flashcanvas instead of excanvas). My memory
was shooting through the roof after just a minute, about 1.2G! Eventually IE
would die a horrible death. After updating to the latest it was like magic.
Been on the page for several minutes and only using like 180M. It looks like
there is still a small memory leak on my specific page. However, there are a
couple other live components on the page which may be causing the issue. Either
way, this is amazing. Thank you for fixing this!!!!!!!!
Original comment by bped...@gmail.com
on 18 Mar 2011 at 8:04
Sadly it does not looks like this is completly fixed...
Using latest chrome or firefox 4 there is still a memory leak on live updating
graphs, it is better than before but still there.
While trying to figure out wat happened I tried the chrome heap profiler and it
reports an increase in HTMLDivElement, the leak doe not happen with the new
realtime example so it may be the axis redraw, could it be the axis labels ?
Ps: the leak happen setData(), setupGrid(), draw() sequence.
Original comment by schmu...@gmail.com
on 11 Apr 2011 at 9:20
What exact steps did you do to verify the code is leaking?
You need to reproduce this with a really simple test case, preferably one of
the bundled examples. You can try modifying the realtime example to do a
setupGrid call. The only reliable way of detecting a leak that I've found so
far is repeating the plot calls a lot of times with timeouts (like the realtime
example). Usually you get a sawtooth pattern with the browser increasing its
memory usage for a while, then collecting garbage, then increasing again.
About the Chrome heap profiler - that doesn't necessarily mean a lot. sIEve for
IE turned out to report false positives.
By the way, just to clarify, there was no leak in Flot per se. The mentioned
changes were updating jQuery to work-around IE problems and adding a
work-around for (mostly) a Chrome bug with canvases.
Original comment by olau%iol...@gtempaccount.com
on 13 Apr 2011 at 9:39
Thanks for the precisions, I think I jumped on a conclusion a little too
quickly.
I ran a test last night by keeping my test application running for a long time
and reducing the timer interval: the only thing observable is the sawtooth
pattern you mentioned but the memory usage stay roughly the same.
Sorry for this :p
Original comment by schmu...@gmail.com
on 13 Apr 2011 at 1:37
I still have a memory problem here, especially in Firefox. I am plotting time
series data and redraw plots every ~30 secs or sooner; if I have lots of plots
on the screen Firefox acts fine but grows sluggish with time, and memory usage
shoots up to over a GB. The browser becomes very slow. Is there another known
memory leak?
Original comment by delso...@gmail.com
on 25 Jun 2012 at 11:35
"In general, it seems the browsers are a bit sluggish in releasing removed DOM
nodes. There are two sources of those in Flot, axis labels and the canvases.
However, I'm planning to land a patch for using canvas text after 0.7 which
would reduce it to the canvases. I need to correct myself here, a) the legend
is also making DOM objects"
I believe I am still seeing this, or a related issue. When I take a heap
snapshot after I empty the plot's DOM element, I am seeing Detached DOM tree
that contain HTMLDivElement for flot-tick-labels. I also see Detached DOM trees
containing HTMLDivElement with className of "flot-base" and "flot-overlay". And
others with className of "flot-text flot-y-axis".
There is definitely a leak.
Do I have to manually call shutdown or something in order to wipe out any
existence of a flot instance from my page?
Original comment by mike.mal...@gmail.com
on 9 Apr 2013 at 3:08
Original issue reported on code.google.com by
bensprac...@gmail.com
on 3 Dec 2009 at 4:48