删除渲染组件时会发生内存泄漏

问题描述 投票:2回答:1

在Vue应用程序中,我遇到内存泄漏,发生这种情况的情况如下:

  • 我们有一个在v-for中呈现的组件,其中包含许多子组件
  • [当从数组中删除相应元素时,v-for重新呈现这些组件,并正确删除与从数组中删除的元素对应的组件。

但是分配的内存永远不会释放,应用程序开始时会占用约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>
javascript vue.js memory-management memory-leaks vuex
1个回答
0
投票

您正在订购vue,以使组件保持活动状态并询问它们为何仍处于活动状态?

解决方案:仅将max属性添加到<keep-alive> sudo-component并传递tabs.length值将迫使它丢弃已删除的那些。

<keep-alive :max="tabs.length">
...
</keep-alive>

请参见keep alive docs

© www.soinside.com 2019 - 2024. All rights reserved.