首页   注册   登录
V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
宝塔
V2EX  ›  JavaScript

关于 setInterval 和 setTimeout 结合使用,内存溢出的问题

  •  
  •   SkYouth · 92 天前 · 1144 次点击
    这是一个创建于 92 天前的主题,其中的信息可能已经有所发展或是发生改变。

    场景:要求一个柱状图柱子动态变化,将柱状图先正常渲染,渲染后执行下面的定时任务,先将值清空再重新赋值原来的值(这种无聊的变化是产品要求的。说动起来炫一点)。

    问题:如果浏览器停留在此页面时候,内存正常(谷歌 F12-->Memory), 但是如果将浏览器切换到其他标签页(假如打开一个百度,停留在百度页),内存会一直增长,直至崩溃


    代码:

    this.intervalId = setInterval(() => {
    	let {myCharts} = this
    	let options = this.myCharts.getOption()
    	let serData = JSON.parse(JSON.stringify(options.series))
        // 把所有数据清空
    	for (let i = 0; i < serData.length; i++) {
    		serData[i].data = null
    	}
        myCharts.setOption({
        	series: serData
    	})
    	setTimeout(() => {
        	// 重新赋值
    		myCharts.setOption({
    			series: options.series
    		})
    	}, 800)
    }, 6000)
    

    在网上试了一个例子: https://echarts.baidu.com/examples/editor.html?c=gauge-car

    在编辑框最下面改为

    setInterval(function (){
        option.series[0].data[0].value = 0;
        option.series[1].data[0].value = 0;
        option.series[2].data[0].value = 0;
        option.series[3].data[0].value = 0;
        myChart.setOption(option,true);
        setTimeout(function() {
            
        option.series[0].data[0].value = (Math.random()*100).toFixed(2) - 0;
        option.series[1].data[0].value = (Math.random()*7).toFixed(2) - 0;
        option.series[2].data[0].value = (Math.random()*2).toFixed(2) - 0;
        option.series[3].data[0].value = (Math.random()*2).toFixed(2) - 0;
        myChart.setOption(option,true);
            
        }, 800);
    },2000);
    

    打开 f12 切走页面看内存。

    问: 有知道原因的同学吗? 我这边一开始想的是内存释放的问题, 那页面激活和未激活为啥会不一样?

    13 回复  |  直到 2019-08-20 09:46:57 +08:00
        1
    JK9993   92 天前
    mac 74.0.3729.169 没这个问题
        2
    imbacc   92 天前
    不清除计时器? j = serData.length 吧
        3
    SkYouth   92 天前
    @JK9993 百度 echarts 那个例子增长会很慢。 我的那段代码在我本地差不多每次 interval 就会增加 15M 左右…… 好几个同事的 pc 这样,window 环境应该是必然增长
        4
    SkYouth   92 天前
    @imbacc 问题不出在 serData.length,删除 setTimeout 即使切换了标签页,内存也稳定。setInterval 会在页面销毁时候清除。
        5
    lenonrade   92 天前
    建议用 log 看看执行顺序,用 Echarts 做过一个柱状图循环显示的小 demo,不知你具体需求是啥
        6
    xenme   92 天前 via iPhone
    猜一下是不是每次 setinterval 都保存一份 local 变量,然后爆了。

    百度那个只是改变了外部变量的属性。和动画啥的。
        7
    ashong   92 天前
    myCharts.setOption 迭代造成的溢出
        8
    momocraft   92 天前
    也许 inactive 页面推迟了一些事件,正常会执行完释放的东西没被释放

    也许用 page visibility API 在页面不活动时暂停计时
        9
    tomato3   92 天前 via Android
    开发工具 snapshot 一下 memery,对比一下多了哪些对象
        10
    SkYouth   91 天前
    @ashong 嗯 应该是 myecharts 的问题,不过停留在页面的时候, 内存不会增加,比较诧异。
        11
    SkYouth   91 天前
    @momocraft 现在的临时解决办法就是通过监听 visibilitychange 来暂停计时。
        12
    SkYouth   91 天前
    @tomato3 好,谢谢 我还真没认真比较过
    关于   ·   FAQ   ·   API   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   1079 人在线   最高记录 5043   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.3 · 22ms · UTC 18:34 · PVG 02:34 · LAX 10:34 · JFK 13:34
    ♥ Do have faith in what you're doing.