javascript - 使用带有ajax的谷歌图表的内存泄漏

标签 javascript memory-leaks google-visualization

我是 javascript 的新手,我无法在某些代码中发现内存泄漏,这些代码每秒使用 ajax 数据更新 google 图表。

我的代码(简化为一个小测试用例):

function TimeLine(id, max) {
    this.chart = new google.visualization.LineChart(document.getElementById(id));
    this.vals = new google.visualization.DataTable();
    this.vals.addColumn('number', 'Index');

    for (var i = 2; i < arguments.length; i++) {
        this.vals.addColumn('number', arguments[i]);
    }

    this.numCols = arguments.length - 2;
    this.max = max;
    this.index = 0;

    this.resourceOptions = {
        'title': 'Memory allocation',
            'width': 360,
        'height': 300
    };
}

TimeLine.prototype.Add = function () {

    if (this.vals.getNumberOfRows() > this.max) {
        this.vals.removeRow(0);
    }

    var row = [this.index];

    for (var i = 0; i < arguments.length; i++) {
        row.push(arguments[i]);
    }

    this.vals.addRow(row);

    this.chart.draw(this.vals, this.options);

    this.index++;
};

function onLoad() {
    window.Timeline = new TimeLine('gauges', 15, 'Alloc');
    drawCharts();
}

function drawCharts() {
    window.Timeline.Add(window.Timeline.index%3);

    setTimeout(drawCharts, 1000);
}

google.load('visualization', '1.0', {
    'packages': ['corechart']
});

google.setOnLoadCallback(onLoad);

我在 64 位 Ubuntu 上使用 chrome 版本 29.0.1547.62。

我将图表包装在一个对象中(希望)让我更容易推理范围和垃圾收集,因为我不太习惯 JS 范围规则。我已经看到很多关于 SO 的类似问题,但据我所知我的代码不应该产生泄漏。使用内存时间轴,我可以看到每次调用 drawCharts 时内存都在攀升,而且大部分内存似乎都被 gc 了,但大约一个小时后,该选项卡的内存达到了 300 MB,它一直在攀升,直到选项卡崩溃。目标是能够将此选项卡作为我们其中一台服务器上当前负载的监控系统长时间保持打开状态,但目前我只能在它被杀死之前保持它几个小时。

我尝试在配置文件选项卡中使用堆快照,如果我比较几次调用 drawCharts 之前和之后的快照,泄漏的对象似乎是来自图表本身的 SVG 元素,但我可能正在解释这些结果不正确。

我已经重现了这个问题:

http://jsfiddle.net/dv5nK/4/

大约 20 分钟后,chrome 中的 about:memory 页面将开始显示高内存消耗,对我来说约为 150 MB。通过将 setTimeout 缩短为 100 毫秒,可以更快地看到这种效果。

编辑:固定内存使用统计

最佳答案

If you are building a new chart for each update (with new google.visualization.SomeChart()) then when you are done with the previous instance, you must call clearChart() on it, otherwise memory will accumulate. Google Charts can't tell that the chart has been garbage collected, and it needs an explicit clearChart() call to unlink event handlers from the DOM.

来源:https://github.com/google/google-visualization-issues/issues/1021

关于javascript - 使用带有ajax的谷歌图表的内存泄漏,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18686041/

相关文章:

javascript - 如何捕获输出 div 中的所有 javascript 警告和错误?

javascript - 有没有地方可以测试代码是否符合 ES5/安全?

javascript - 更改导航链接的样式 - 包括下一个和上一个按钮

javascript - 如何在页面加载时启用 Extjs 过滤器

android - Activity 泄露了原来添加的窗口

javascript - 谷歌在一页上绘制两个条形图

google-visualization - 如何通过谷歌电子表格应用程序自定义代码更新或管理带注释的时间线图表?

android - 内存问题 - fragment

c++ - 与 replaceChild 相关的内存泄漏

javascript - 如何将字符串更改为 Google 图表数据