Memory leak help!

338 views
Skip to first unread message

Slugsie

unread,
Jan 28, 2017, 7:42:07 PM1/28/17
to Google Visualization API

I'm pretty new to Javascript, and I'm trying to write a web page that displays the utilisation of our servers. I have it all working fine, except for the fact that over time the page consumes more and more memory, until eventually the browser just gives up and displays an out of memory error. If I disable the code that displays the graphs (it still collates the data, just doesn't display the resultant graphs) then memory usage stays pretty flat and well under control (typically under 25,000K - all memory stats taken from Chromes Task Manager). Add the graphs back in and it starts around 40,000K, but grows and grows. I've seen it reach nearly 1GB after many hours. The page is intended as a dashboard display, running all the time on a Smart TV, with the figures updated every minute.

 

Here is the code that draws the graphs:

 

	function drawAChart(dataSource, chartHead, elementDIV){
		// // Take the data, and draw the actual graph
		dataSource.unshift(chartHead);
		var dataS = new google.visualization.arrayToDataTable(dataSource);
		var chartS = new google.visualization.ColumnChart(document.getElementById(elementDIV));
		chartS.draw(dataS, options);
		// Try and clean up to help the GC
		dataS = undefined;
		chartS = undefined;
		dataSource = undefined;
	}

When I comment out the lines relating to chartS then the memory usage stays low.

 

dataSource is an array, typically in the form [['Server name',<%age number 0-100>,<colour>], ...]

chartHead is typically ['Server','Useage', {role: 'style'}]

elementDIV is just the name of the DIV that the graph is displayed in.

 

The chart options are:

	var options = {
		height: 130,
		legend: {
			position: 'none'
		},
		chartArea: {
			left: 50,
			top: 10,
			width: '95%',
			height: '75%'
		},
		vAxis: {
			viewWindow: {
				min: 0,
				max: 100
			},
			ticks: [{v:0, f:"0%"}, {v:25, f:"25%"}, {v:50, f:"50%"}, {v:75, f:"75%"}, {v:100, f:"100%"}]
		},
		bar: {
			groupWidth: '95%'
		}
	};

 

I know I'm missing something, probably obvious to any seasoned Javascript devs, but I just can't figure it out. Hopefully I've given enough info for someone to point me in the right direction.

Daniel LaLiberte

unread,
Jan 28, 2017, 9:58:07 PM1/28/17
to Google Visualization API
I would guess you are calling drawAChart more than one time, otherwise there is no reason the memory would grow over time.  Are you keeping the elementDIVs around after you are done with them?  Or is it the same element every time?  

If you do thrown the unused elements away, then there may still be memory leaks involving event handling bound to those elements.  You can avoid some leaks by clearing the chart that is associated with those elements.  chart.clearChart() is what you want to call.  Ideally, this shouldn't be necessary, but some browsers may still have issues with cleaning up the unused elements, even when they are removed.

--
You received this message because you are subscribed to the Google Groups "Google Visualization API" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-visualization-api+unsub...@googlegroups.com.
To post to this group, send email to google-visualization-api@googlegroups.com.
Visit this group at https://groups.google.com/group/google-visualization-api.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-visualization-api/476a7e9d-5afa-49fb-a64c-160454d42ca3%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.



--

Slugsie

unread,
Jan 29, 2017, 6:19:00 AM1/29/17
to Google Visualization API
Yes, each minute drawAChart is called for each of the 3 charts. The whole page is re-drawn from a controlling routine that is called every minute by a setInterval call. There are 3 DIVs on the page, one for each chart. Every minute the same 3 DIVs are reused.

When should I be calling chart.clearChart? If I call it after the chart has been created then no chart is drawn, but the chartS object only exists inside the drawAChart routine, so that's the only place it can be used. Or am I missing something? 

I think I may try and use some other chart control and see if I get the same issues.

Daniel LaLiberte

unread,
Jan 29, 2017, 12:02:20 PM1/29/17
to Google Visualization API
If you are redrawing the whole page by replacing the whole document, that ought to clear up any memory leak, but old versions of IE used to have memory leaks even if you did that.  

But I suspect you mean the contents of the page body (or some subset) is redrawn, keeping all the same JavaScript around.  This could accumulate removed elements and attached event handlers longer than you need.  

The proper way to clear the chart is just before you want to delete it from the page, or replace it with a new one.  That means you would have to store the chart object somewhere outside of drawAChart.

It would be better if you could use the same elements and even the same chart objects.  You don't have to recreate all of that just to draw new versions of the charts with new data or options.  Just call chart.draw() with the new data or options.
 

--
You received this message because you are subscribed to the Google Groups "Google Visualization API" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-visualization-api+unsub...@googlegroups.com.
To post to this group, send email to google-visualization-api@googlegroups.com.
Visit this group at https://groups.google.com/group/google-visualization-api.

For more options, visit https://groups.google.com/d/optout.

Slugsie

unread,
Jan 29, 2017, 5:16:46 PM1/29/17
to Google Visualization API
Yeah, I'm just redrawing the parts of the page that are relevant.

I've taken on board your comments, reworked a few things, and the memory usage does seem to be a bit more sensible. It's fluctuating between about 60,000K and 70,000K after running for several hours. GC in Chrome does seem a little woeful.

Thanks for your pointers. :)

Yuhao Feng

unread,
May 9, 2017, 1:22:06 PM5/9/17
to Google Visualization API
Hi I'm having a similiar issue, I'm using websockets to passing data every second. So I'm basically redrawing the chart whenever theres new data coming in.

My memory consumption goes up to 200,000 in like few minutes. 

Can you explain a little about how you got it fixed? Thanks so much
Reply all
Reply to author
Forward
0 new messages