我正在写一个 MMO RTS。在前面,我使用 Vue。以给定的频率,更新的数据通过 WebSoket 从服务器到达。自然地,数据是放在Vuex中,由组件监控。
发现每次新提交都会增加内存消耗。如果您让选项卡保持打开状态,浏览器会崩溃。
下面是演示问题的代码:运行它,打开控制台 - 内存选项卡 - 并观察
const data = {
lvl: 0,
a: {
lvl: 1,
b: {
lvl: 2,
c: {
lvl: 3
}
}
}
}
const store = new Vuex.Store({
state: {
count: 0,
data: []
},
mutations: {
increment(state) {
state.count++;
},
set_data(state, payload) {
state.data = payload;
}
},
actions: {
increment(context) {
setInterval(() => {
context.commit('increment');
const newData = JSON.parse(JSON.stringify(data));
context.commit('set_data', newData);
}, 500);
}
}
});
var app = new Vue({
store,
el: '#app',
template: `
<div>{{count}}</div>`,
data() {
return {
count: 0,
d: window.performance.memory.totalJSHeapSize
};
},
created() {
this.$store.dispatch('increment');
},
watch: {
'$store.state.data': {
deep: true,
handler() {
this.count = this.$store.state.count;
}
}
}
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.6.1/vue.js"></script>
<script src="https://unpkg.com/vuex@2.0.0"></script>
<div id="app"></div>
这个消息让我很难过。对如何解决这个问题还没有清晰的认识。
UPD 发现了一个细微差别:如果 html 文件,在这个例子中,不是通过服务器打开的,而是在地址栏中使用完整路径打开的,那么就没有泄漏。
我认为不是VUEX,而是订阅它的组件。最有可能的是,其中一个将数据添加到本地集合或数组中,并且在更改存储后不会对其进行清理。
尝试禁用所有更改订阅,直到找到一个组件一个组件。
事实证明,问题出在 Vuex 上。插入最新版本(3.1.2)修复了我演示中的泄漏。
但是,不幸的是,在我的应用程序中,泄漏并没有消失。但那是另一个故事
故事继续:因此,我得出结论,泄漏在开发模式下尽可能多地表现出来。因此,我有2个嫌疑人:我自己
vue/vuex和vue-dev-tools,而在检查内存片后,我更倾向于vue-dex-tools。因为 内存泄漏本身“闻起来”不太好,无论如何我都试图将其最小化。为此,我必须在深度复制它们之后在所有“薄的地方”(手表、计算、存储......)中分配对象。经过这样的操作,在开发模式下,垃圾收集器的工作变得引人注目。最终,消耗的内存量仍在增长,但回扣已变得明显。至于专业模式,那里的一切都很棒。