在我们的项目中,前后台使用 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[containerIndex] = 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
不多说 这个代码看起来真难受
不出问题见鬼了 |