大多数情况下,垃圾回收器会帮我们及时释放内存,一般不会发生内存泄漏。但是有些场景是内存泄漏的高发区,我们在使用的时候一定要注意:

  • 我们在开发的时候经常会使用console在控制台打印信息,但这也会带来一个问题:被console使用的对象是不能被垃圾回收的,这就可能会导致内存泄漏。因此在生产环境中不建议使用console.log()的理由就又可以加上一条避免内存泄漏了。

  • 被全局变量、全局函数引用的对象,在Vue组件销毁时未清除,可能会导致内存泄漏

     1// Vue3
     2<script setup>
     3import {onMounted, onBeforeUnmount, reactive} from 'vue'
     4const arr = reactive([1,2,3]);
     5onMounted(() => {
     6    window.arr = arr; // 被全局变量引用
     7    window.arrFunc = () => {
     8        console.log(arr); // 被全局函数引用
     9    }
    10})
    11// 正确的方式
    12onBeforeUnmount(() => {
    13    window.arr = null;
    14    window.arrFunc = null;
    15})
    16</script>
  • 定时器未及时在Vue组件销毁时清除,可能会导致内存泄漏

     1// Vue3
     2<script setup>
     3import {onMounted, onBeforeUnmount, reactive} from 'vue'
     4const arr = reactive([1,2,3]);
     5const timer = reactive(null);
     6onMounted(() => {
     7    setInterval(() => {
     8        console.log(arr); // arr被定时器占用,无法被垃圾回收
     9    }, 200);
    10    // 正确的方式
    11    timer = setInterval(() => {
    12        console.log(arr);
    13    }, 200);
    14})
    15// 正确的方式
    16onBeforeUnmount(() => {
    17    if (timer) {
    18        clearInterval(timer);
    19        timer = null;
    20    }
    21})
    22</script>

    setTimeoutsetInterval两个定时器在使用时都应该注意是否需要清理定时器,特别是setInterval,一定要注意清除。

  • 绑定的事件未及时在Vue组件销毁时清除,可能会导致内存泄漏

    绑定事件在实际开发中经常遇到,我们一般使用addEventListener来创建。

     1// Vue3
     2<script setup>
     3import {onMounted, onBeforeUnmount, reactive} from 'vue'
     4const arr = reactive([1,2,3]);
     5const printArr = () => {
     6    console.log(arr)
     7}
     8onMounted(() => {
     9    // 监听事件绑定的函数为匿名函数,将无法被清除
    10    window.addEventListener('click', () => {
    11        console.log(arr); // 全局绑定的click事件,arr被引用,将无法被垃圾回收
    12    })
    13    // 正确的方式
    14    window.addEventListener('click', printArr);
    15})
    16// 正确的方式
    17onBeforeUnmount(() => {
    18    // 注意清除绑定事件需要前后是同一个函数,如果函数不同将不会清除
    19    window.removeEventListener('click', printArr);
    20})
    21</script>
  • 被自定义事件引用,在Vue组件销毁时未清除,可能会导致内存泄漏

    自定义事件通过emit/on来发起和监听,清除自定义事件和绑定事件差不多,不同的是需要调用off方法

     1// Vue3
     2<script setup>
     3import {onMounted, onBeforeUnmount, reactive} from 'vue'
     4import event from './event.js'; // 自定义事件
     5const arr = reactive([1,2,3]);
     6const printArr = () => {
     7    console.log(arr)
     8}
     9onMounted(() => {
    10    // 使用匿名函数,会导致自定义事件无法被清除
    11    event.on('printArr', () => {
    12        console.log(arr)
    13    })
    14    // 正确的方式
    15    event.on('printArr', printArr)
    16})
    17// 正确的方式
    18onBeforeUnmount(() => {
    19    // 注意清除自定义事件需要前后是同一个函数,如果函数不同将不会清除
    20    event.off('printArr', printArr)
    21})
    22</script>

除了及时清除监听器、事件等,对于全局变量的引用,我们可以选择WeakMapWeakSet等弱引用数据类型。这样的话,即使我们引用的对象数据要被垃圾回收,弱引用的全局变量并不会阻止GC。

个人笔记记录 2021 ~ 2025