在Vue应用程序中,我遇到内存泄漏,发生这种情况的情况如下:
但是分配的内存永远不会释放,应用程序开始时会占用约30-40 MB的RAM,当呈现v-for时,它会增加到200MB的RAM(最终会超过1GB,并在崩溃时导致浏览器崩溃或在切换时添加更多元素)。除去元素后,它稳定地保持在200MB(即使是手动进行垃圾收集),因此看起来它保留了我的组件。
我已经尝试通过堆快照定位问题,但是它仅将子组件显示为保留器。我无法找到导致该组件没有被垃圾收集的原因。我尝试用this.$root.off
取消订阅根目录上的所有事件侦听器,但这似乎根本没有帮助...
代码本身是机密的,所以我不能只共享它,但是,如果需要一些代码来理解这个问题,请告诉我,所以我可以提供一个复制的示例。
有人对我如何解决此问题有任何想法,或对如何找到此内存泄漏的原因有任何想法吗?
UPDATE
这是在v-for中呈现组件的组件:
<template>
<b-tabs card class="tabMenu" v-model="index">
<b-tab v-for="(tab) in tabs" @click="doSomething" @change="doSomething">
<TabComponent :tab="tab"></TabComponent>
</b-tab>
</b-tabs>
</template>
<script>
import TabComponent from "./TabComponent";
export default {
components: {
TabComponent,
},
created: function () {
this.$root.$on("addTab", this.addTab);
},
data: function () {
return {
tabs: this.$store.state.tabs,
}
},
beforeDestroy: function(){
this.$root.$off("addTab");
},
methods: {
addTab(tab) {
this.$store.commit("addTab", {tab: tab});
},
}
};
</script>
及其呈现的选项卡组件:
<template>
<div @mousedown.stop>
<!-- Other components are loaded here but not relevant -->
<div>
<div v-show="conditionA">
<resize-observer @notify="doSomething" v-if="conditionC"></resize-observer>
<!-- This component renders many SVG elements which can be found in the heapsnapshot as DetachedSvgElements when the parent is not present anymore -->
<VisualizationComponent v-show="conditionD"
:tab="tab"></VisualizationComponent>
</div>
</div>
</div>
</template>
<script>
export default {
components: {
},
props: {
tab: TabObject,
},
data: function () {
return {
}
},
watch: {
// Some watchers
},
mounted: function () {
this.$nextTick(function () {
// Do some calculations
this.$root.$emit("updateSomething");
});
},
created: function(){
this.$root.$on("listen", this.doSomething);
// And listen to more events
},
beforeDestroy: function(){
this.$root.$off("listen");
// And unsubscribe all others
},
computed: {
// Quite a lot of computed props
},
methods: {
// And also many methods for data processing
}
}
</script>
您正在订购vue,以使组件保持活动状态并询问它们为何仍处于活动状态?
解决方案:仅将max
属性添加到<keep-alive>
sudo-component并传递tabs.length
值将迫使它丢弃已删除的那些。
<keep-alive :max="tabs.length">
...
</keep-alive>