jhy*_*yap 6 javascript internet-explorer memory-leaks memory-management d3.js
我尝试使用动态数据模拟实时图表d3.js.我正在使用IE-10浏览器运行它.
我遇到了一个问题,即如果让Web应用程序运行一段时间,我的IE浏览器的内存将逐渐增加.
我谷歌搜索了造成这个问题的可能原因.
我想到了两件事情要讨论:
计时器防止IE的垃圾收集
d3图表之后不会释放内存 data.shift()
我的问题:
我怎么能诊断我的问题是否真的来自讨论1或2或两者都没有?
我怎么能解决内存问题?
您可能需要下载代码并在一段时间内运行它并监视iexplorer.exe使用资源监视器以识别问题.
谢谢.
源代码:
<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 <b>Interpolation:</b> basis <b>Animation:</b> true <b>Transition:</b> 1000ms <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's 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's 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>
Run Code Online (Sandbox Code Playgroud)
小智 4
我按照你所说的尝试了 2 个小时,最初内存使用量为 56 MB,最终内存使用量约为 56.8 MB。这意味着在某些特殊情况下只有 0.8 MB 的差异。但我可以帮助您找到发生内存负载的确切点。只需按照步骤一一进行即可。
按F12打开IE的“开发者工具”
转到内存(相机符号或 CTRL+7)
单击开始分析会话(顶部的绿色播放按钮)
拍摄堆快照以创建基线。
现在每 10 或 15 分钟拍摄一次快照
执行此操作需要多少小时(在您的情况下为 2 小时)
一旦分析完成所需的时间,就停止它并通过比较堆快照从头开始分析。
如果开始和结束的内存差异太大,请通过分析快照中的内存差异来检查内存增加是从哪里开始的。
在这里您可以检查进程使用的内存差异(以字节或 KB 为单位)。
检查哪个函数、变量或操作造成了内存问题。很可能是重复进行一些计算,以便这些计算中使用的变量不会从某个时间点被释放。在分析内存流时,我看到了一些“Ba,p”,“n,p”,“Wa,n,p”等。我相信使用这些变量的函数正在为您带来问题。
笔记
如果你使用UI Responsiveness (CTRL+5),你可以很容易地看到垃圾收集是由IE自动执行的。
| 归档时间: |
|
| 查看次数: |
2168 次 |
| 最近记录: |