在我们的项目中,前后台使用 websocket 连接,整个项目使用的 vue 框架。websocket 后台传输频率为4 次 /s,每次的数据量为2KB。前台使用 onmessage 方法接收到数据之后进行处理并使用 this.$set()方法将数据更新进数组中。在这个过程中出现了内存泄露的问题,表现形式为 chrome 内存急剧升高。
在百度和 google 之后,并经过自己的测试,发现 Vue 过于的 this.$set 方法会导致内存泄漏,而直接赋值进行替换则不会,于是将所有的 this.$set 方法更新数据改为了重新复制,发现有效降低了内存泄露的问题。但是并没有完全解决。在测试中,我将 websocket 的 onmessage 方法全部注释掉之后,发现 chrome 内存上涨的情况于前面修改之后上涨的速度一致。当将 websocket 整个注释掉之后 chrome 内存才不再上涨。
这是处理数据的逻辑
function onMessage(evt, containerName) { var cOntainerIndex= vm.containerJson[containerName]; if (!vm.flaginit[containerIndex]) { try { var request = JSON.parse(evt.data); }catch (e) { console.log(e); return false; } var newIndex = containerIndex; for (var i = 0; i < vm.pageContainer.length; i++) { if (vm.pageContainer[i].Name == containerName) { newIndex = i; break; } } vm.$set(vm.dynaDatas, containerIndex, request); console.log(request); if (request.msg != 'Open') { if (vm.pageContainer[newIndex].Type === "remote" || vm.pageContainer[newIndex].Type === "data") { if (request.Live != undefined) { that.circleId[newIndex] = 0; //设置圈次索引值为 0,不然实时数据过来以后,被选中的圈次显示错误(不只第一圈被选中) that.$set(that.stopOrStart, containerIndex, 'true'); that.clickButton(newIndex, true); that.realTimePlayList(vm.pageContainer[newIndex].Name, request.Live, playListNum, 1, newIndex); that.timebar[containerIndex] = that.$refs.progress[0].offsetWidth; //进度条的长度 clearInterval(that.PlayBackMode[containerIndex]); var name = that.pageContainer[newIndex].Name; // that.PlayBackMode[containerIndex] = setInterval(function () { // // that.getPlayList(name, request.Live, playlistsix, 1, containerIndex); // }, 5000); that.pageContainer[newIndex].showData = "true";//数据列表显示数据 } else { if (request.data != "{}" && request.statuscode == "200" && request.msg != "Pause" && request.data.Time != undefined) { if (request.data.Time != undefined) { vm.dataTime[containerIndex] = request.data.Time;//h5 显示的数据时间 vm.noData[containerIndex] = new Date(request.data.Time.split("-")[0].split(":").join("-") + ' ' + request.data.Time.split("-")[1]).getTime(); vm.shipTime[containerIndex] = formatDuring(vm.noData[containerIndex] - standardTime); } if (vm.pageContainer[newIndex].select == "true") { //回放模式 var data = [vm.test]; console.log(vm.timeBar[0]); if (data.length != 0) { data[vm.activeTimeIndex[containerIndex]].Active = (vm.noData[containerIndex] - 1502727683750) / (1502727683779 - 1502727683750); //当前圈次数据段最后一段和下一圈次数据段是连续的 if (vm.timeBar[containerIndex] == "4" && data[data.length - 1].Active >= data[data.length - 1].End) { vm.websocket[containerIndex].send("Pause"); that.$set(that.stopOrStart, containerIndex, 'false'); that.clickButton(newIndex, false); } } function beforeTimeEnd(m) {//递归调用,更改当前间隔时间的前一段,状态为播放结束 if (m <= -1) { return 1 } else { data[m].Active = data[m].End - 0; return beforeTimeEnd(m - 1); } } function afterTimeStart(m) {//递归调用,更改当前间隔时间的后一段,状态为未播放 if (m >= data.length) { return 1 } else { data[m].Active = data[m].Start; return afterTimeStart(m + 1); } } for (var m = 0, l = data.length; m < l; m++) { if (data[vm.activeTimeIndex[containerIndex]].Active >= data[m].Start && data[vm.activeTimeIndex[containerIndex]].Active <= data[m].End) { data[m].Active = data[vm.activeTimeIndex[containerIndex]].Active; that.activeTimeIndex[containerIndex] = m; beforeTimeEnd(m - 1); afterTimeStart(m + 1); } } data = null; startTimeStamp = null; endTimeStamp = null; } else if (request.data == "") { var circle = vm.pageContainer[newIndex].listData[0].Circle[vm.timeBar[containerIndex]]; var data = vm.pageContainer[newIndex].listData[0].Circle[vm.timeBar[containerIndex]].Data; if (data[vm.activeTimeIndex[containerIndex]].Active > data[data.length - 1].Start) { if (vm.timeBar[containerIndex] == "4" && request.data == "") { //判断当前容器第 5 圈最后一段数据(不等于 End 的情况下)播放完毕,向后台发送停止命令 vm.websocket[containerIndex].send("Pause"); that.$set(that.stopOrStart, containerIndex, 'false'); that.clickButton(newIndex, false); } else { that.$set(that.stopOrStart, containerIndex, 'false'); that.clickButton(newIndex, false); circle.select = "false"; vm.timeBar[containerIndex]++; that.circleId[cotainerIndex] = vm.timeBar[containerIndex];//容器对应圈数的索引 vm.activeTimeIndex[containerIndex] = 0; that.timebar[containerIndex] = that.$refs.progress[0].offsetWidth; //进度条的长度 circle.select = "true"; that.$set(that.stopOrStart, containerIndex, 'true'); that.clickButton(newIndex, true); if (data.length != 0) { vm.nextCircvarime[containerIndex] = Math.round(data[0].Start * 90 * 60); vm.nextCircvarimeHour[containerIndex] = parseInt(vm.nextCircvarime[containerIndex] / 3600); vm.nextCircvarimeMin[containerIndex] = parseInt(vm.nextCircvarime[containerIndex] % 3600 / 60); vm.nextCircvarimeSec[containerIndex] = parseInt(vm.nextCircvarime[containerIndex] % 3600 % 60); vm.nextCircvarimeH[containerIndex] = Number(vm.nextCircvarimeHour[containerIndex]) + Number(circle.Start[1].split(":")[0]); vm.nextCircvarimeM[containerIndex] = Number(vm.nextCircvarimeMin[containerIndex]) + Number(circle.Start[1].split(":")[1]); vm.nextCircvarimeS[containerIndex] = Number(vm.nextCircvarimeSec[containerIndex]) + Number(circle.Start[1].split(":")[2]); if (vm.nextCircvarimeS[containerIndex] > 60) { vm.nextCircvarimeS[containerIndex] = vm.nextCircvarimeS[containerIndex] - 60; vm.nextCircvarimeM[containerIndex] = vm.nextCircvarimeM[containerIndex] + 1; } else { if (vm.nextCircvarimeM[containerIndex] > 60) { vm.nextCircvarimeM[containerIndex] = vm.nextCircvarimeM[containerIndex] - 60; vm.nextCircvarimeH[containerIndex] = vm.nextCircvarimeH[containerIndex] + 1; } else { if (vm.nextCircvarimeH[containerIndex] > 23) { vm.nextCircvarimeH[containerIndex] = 0; } else { vm.nextCircvarimeH[containerIndex] = vm.nextCircvarimeH[containerIndex]; } vm.nextCircvarimeM[containerIndex] = vm.nextCircvarimeM[containerIndex]; } vm.nextCircvarimeS[containerIndex] = vm.nextCircvarimeS[containerIndex]; } vm.nextCircvarime[containerIndex] = vm.nextCircvarimeH[containerIndex] + ":" + vm.nextCircvarimeM[containerIndex] + ":" + vm.nextCircvarimeS[containerIndex] + ":" + "000"; vm.nextstartNextTime[containerIndex] = circle.Start[0] + "-" + vm.nextCircvarime[containerIndex]; if (vm.pageContainer[newIndex].Type === "remote" || vm.pageContainer[newIndex].Type === "data") { vm.websocket[containerIndex].send("Play" + ";" + vm.nextstartNextTime[containerIndex] + ";"); vm.pageContainer[newIndex].showData = "true"; } } } } else { vm.activeTimeIndex[containerIndex]++; vm.stageTime[containerIndex] = Math.round(data[vm.activeTimeIndex[containerIndex]].Start * 90 * 60); vm.stageTimeHour[containerIndex] = parseInt(vm.stageTime[containerIndex] / 3600); vm.stageTimeMin[containerIndex] = parseInt(vm.stageTime[containerIndex] % 3600 / 60); vm.stageTimeSec[containerIndex] = parseInt(vm.stageTime[containerIndex] % 3600 % 60); vm.stageTimeH[containerIndex] = Number(vm.stageTimeHour[containerIndex]) + Number(circle.Start[1].split(":")[0]); vm.stageTimeM[containerIndex] = Number(vm.stageTimeMin[containerIndex]) + Number(circle.Start[1].split(":")[1]); vm.stageTimeS[containerIndex] = Number(vm.stageTimeSec[containerIndex]) + Number(circle.Start[1].split(":")[2]); if (vm.stageTimeS[containerIndex] > 60) { vm.stageTimeS[containerIndex] = vm.stageTimeS[containerIndex] - 60; vm.stageTimeM[containerIndex] = vm.stageTimeM[containerIndex] + 1; } else { if (vm.stageTimeM[containerIndex] > 60) { vm.stageTimeM[containerIndex] = vm.stageTimeM[containerIndex] - 60; vm.stageTimeH[containerIndex] = vm.stageTimeH[containerIndex] + 1; } else { if (vm.stageTimeH[containerIndex] > 23) { vm.stageTimeH[containerIndex] = 0; } else { vm.stageTimeH[containerIndex] = vm.stageTimeH[containerIndex]; } vm.stageTimeM[containerIndex] = vm.stageTimeM[containerIndex]; } vm.stageTimeS[containerIndex] = vm.stageTimeS[containerIndex]; } vm.nextTime[containerIndex] = vm.stageTimeH[containerIndex] + ":" + vm.stageTimeM[containerIndex] + ":" + vm.stageTimeS[containerIndex] + ":" + "000"; vm.CircleStartTime[0] = vm.CircleStartTime[0]; vm.startNextTime[containerIndex] = vm.CircleStartTime[0] + "-" + vm.nextTime[containerIndex]; vm.websocket[containerIndex].send("Play" + ";" + vm.startNextTime[containerIndex] + ";"); vm.pageContainer[newIndex].showData = "true"; } } } var detailData = []; var k = 0; if (request.data != undefined) { if (request.data.Params != undefined) { for (var j in request.data.Params) { var dataObj = {}; if (j != "Image") { dataObj.name = j; dataObj.cOntent= request.data.Params[j].split(";"); detailData[k++] = dataObj; } } //数值数据刷新 for (var j = 0; j < vm.pageContainer[newIndex].Topic.length; j++) { for (var k = 0; k < detailData.length; k++) { if (vm.pageContainer[newIndex].Topic[j].Codename["0"].COntent== detailData[k].name) { var dataObj = {}; dataObj.code = detailData[k].content[0]; dataObj.result = detailData[k].content[1]; dataObj.mean = detailData[k].content[2]; dataObj.beyOnd= detailData[k].content[3]; vm.$set(vm.pageContainer[newIndex].Topic[j], "dynData", dataObj); } } } } else { request.data = detailData; } } } } }
注释掉 onmsaage 方法依旧继续上涨
// name.Onmessage= function (evt) { // // onMessage(evt, containerName); // };
希望在使用 websocket 的过程中 chrome 内存不在继续上涨
![]() | 1 arslion 2019-01-30 14:09:00 +08:00 为什么要这样大段大段冲击波式地写代码? 没有冒犯的意思,是真的不理解 |
2 CDL 2019-01-30 14:15:46 +08:00 这一大坨的代码... 看不下去 |
![]() | 3 vigossliao 2019-01-30 14:44:30 +08:00 不多说 这个代码看起来真难受 不出问题见鬼了 |