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

2019-08-19 16:56:19 +08:00
 SkYouth

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

问题:如果浏览器停留在此页面时候,内存正常(谷歌 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 切走页面看内存。

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

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

百度那个只是改变了外部变量的属性。和动画啥的。
ashong
2019-08-19 18:39:37 +08:00
myCharts.setOption 迭代造成的溢出
momocraft
2019-08-19 18:44:20 +08:00
也许 inactive 页面推迟了一些事件,正常会执行完释放的东西没被释放

也许用 page visibility API 在页面不活动时暂停计时
tomato3
2019-08-19 18:45:46 +08:00
开发工具 snapshot 一下 memery,对比一下多了哪些对象
SkYouth
2019-08-20 08:57:52 +08:00
@ashong 嗯 应该是 myecharts 的问题,不过停留在页面的时候, 内存不会增加,比较诧异。
SkYouth
2019-08-20 08:58:30 +08:00
@momocraft 现在的临时解决办法就是通过监听 visibilitychange 来暂停计时。
SkYouth
2019-08-20 08:58:47 +08:00
@tomato3 好,谢谢 我还真没认真比较过
royzxq
2019-08-20 09:46:57 +08:00

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/593230

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX