Was memory gradually increased using d3 for real-time graphics?

I tried to simulate a real-time diagram with dynamic data using d3.js I run this using IE-10 browser.

My source code

I am facing a problem when the memory of my IE browser will gradually increase if the web application is working for a while.

I was looking for a possible cause of this problem on Google.

Two thoughts come to my mind:

  • Timer prevents IE garbage collection

  • data.shift() chart does not free memory after data.shift()

My question is:

  • How can I diagnose if my problem really came from discussion 1 or 2 or not?

  • How can I solve the memory problem?

You may need to download the code and run it after a while and monitor iexplorer.exe using the resource monitor to identify the problem.

Thanks.

Source:

 <html> <head> <title>Animated Sparkline using SVG Path and d3.js</title> <script src="http://mbostock.github.com/d3/d3.v2.js"></script> <style> /* tell the SVG path to be a thin blue line without any area fill */ path { stroke: steelblue; stroke-width: 1; fill: none; } </style> </head> <body> <span> <b>Size:</b> 300x30 &nbsp;&nbsp;<b>Interpolation:</b> basis &nbsp;&nbsp;<b>Animation:</b> true &nbsp;&nbsp;<b>Transition:</b> 1000ms &nbsp;&nbsp;<b>Update Frequency:</b> 1000ms <div id="graph1" class="aGraph" style="width:300px; height:30px;"></div> </span> <script> var myTimer; function FeedDataToChart(id, width, height, interpolation, animate, updateDelay, transitionDelay, data, startIndex) { // create an SVG element inside the #graph div that fills 100% of the div var graph = d3.select(id).append("svg:svg").attr("width", "80%").attr("height", "80%"); // X scale will fit values from 0-10 within pixels 0-100 var x = d3.scale.linear().domain([0, 48]).range([10, width-10]); // starting point is -5 so the first value doesn't show and slides off the edge as part of the transition // Y scale will fit values from 0-10 within pixels 0-100 var y = d3.scale.linear().domain([0, 20]).range([height-10, 10]); // create a line object that represents the SVN line we're creating var line = d3.svg.line() // assign the X function to plot our line as we wish .x(function(d,i) { // verbose logging to show what actually being done //console.log('Plotting X value for data point: ' + d + ' using index: ' + i + ' to be at: ' + x(i) + ' using our xScale.'); // return the X coordinate where we want to plot this datapoint return x(i); }) .y(function(d) { // verbose logging to show what actually being done //console.log('Plotting Y value for data point: ' + d + ' to be at: ' + y(d) + " using our yScale."); // return the Y coordinate where we want to plot this datapoint return y(d); }) .interpolate(interpolation) var counter = startIndex; //var myData = data.slice(); // display the line by appending an svg:path element with the data line we created above graph.append("svg:path").attr("d", line(data)); // or it can be done like this function redrawWithAnimation() { // update with animation graph.selectAll("path") .data([data]) // set the new data .attr("transform", "translate(" + x(1) + ")") // set the transform to the right by x(1) pixels (6 for the scale we've set) to hide the new value .attr("d", line) // apply the new data values ... but the new value is hidden at this point off the right of the canvas .transition() // start a transition to bring the new value into view .ease("linear") .duration(transitionDelay) // for this demo we want a continual slide so set this to the same as the setInterval amount below .attr("transform", "translate(" + x(0) + ")"); // animate a slide to the left back to x(0) pixels to reveal the new value } function redrawWithoutAnimation() { // static update without animation graph.selectAll("path") .data([data]) // set the new data .attr("d", line); // apply the new data values } function stopTimer() { clearInterval(myTimer); myTimer = null; graph.selectAll("path").data([data]).remove().append("svg:path").attr("d", line); buffer = null; signalGenerator(); } function startTimer() { if (myTimer == null) { myTimer = setInterval(function() { if (counter < data.length - 1) { var v = data.shift(); // remove the first element of the array data.push(v); // add a new element to the array (we're just taking the number we just shifted off the front and appending to the end) if(animate) { redrawWithAnimation(); } else { redrawWithoutAnimation(); } counter++; } else { //alert("no more data in buffer"); stopTimer(); counter = startIndex; } }, updateDelay); } } startTimer(); } var buffer; function signalGenerator() { if (buffer == null) { buffer = new Array(100); var i; for (i = 0; i < buffer.length; i++) { buffer[i] = Math.random() * 10; } FeedDataToChart("#graph1", 300, 300, "basis", true, 100, 100, buffer, 0); } } function startGenerator() { signalGenerator(); } startGenerator(); </script> </body> </html> 
+6
source share
1 answer

I tried, as you said, for 2 hours, and 56 MB of memory was initially loaded, and 56.8 MB at the end. This means only 0.8 MB difference with some exceptional cases. But I can help you find the exact point at which memory loading occurs. Just follow the steps one by one.

  • Open IE Developer Tools by pressing F12

  • Go to memory (camera symbol or CTRL + 7)

  • Click "Initial Profiling Session" (Green button at the top)

  • Take a picture with a bunch to create a baseline.

  • Now take a bunch of pictures every 10 or 15 minutes

  • Do it in how many hours you need (in your case 2 hours)

  • Once profiling is done for the desired time, stop it and analyze it from the beginning by comparing the heap snapshots.

  • If the difference in memory at the beginning and at the end is so large, check where this memory increase began by analyzing the memory difference in the image.

  • Here you can check the difference in memory used by the process, in bytes or KB.

  • Check which function or variable or operation is creating a memory problem. Most likely, some calculations that are repeatedly performed so that the variables used in these calculations are not freed from a certain point in time. When analyzing the memory stream, I saw some "Ba, p", "n, p", "Wa, n, p", etc. I believe that functions using these variables pose a problem for you.

Note

If you use the Responsiveness of the interface (CTRL + 5), you can easily see that the garbage collection runs IE automatically.

+3
source

All Articles