记一个闭包导致的内存泄漏问题

记一个闭包导致的内存泄漏问题

最近写代码碰到闭包导致的内存泄漏问题,记录一下

问题描述

问题发生在runJs函数中,该函数的功能是将js代码运行,返回运行结果,如下:

/**
 * 运行js代码
 * @param code js代码
 * @returns {Promise<unknown>}
 */
export function runJs (code) {
  return new Promise((resolve, reject) => {
    let worker = new Worker("worker.js");
    worker.postMessage(code);

    worker.onmessage = (event) => {
      resolve(event)
      worker.terminate()
    };

    worker.onerror = (error) => {
      reject(error)
      worker.terminate()
    }
  })
}

在以上函数中,onmessage、onerror函数存在闭包,因为在onmessage和onerror函数中存在对外层函数中worker变量的引用。在外层函数执行完毕后,worker不会被垃圾回收,也就造成每执行一次runJs函数,就会产生一个Worker实例且不被释放

解决方案

一:使用一次性事件

/**
 * 运行js代码
 * @param code js代码
 * @returns {Promise<unknown>}
 */
export function runJs (code) {
  return new Promise((resolve, reject) => {
    let worker = new Worker("worker.js");
    worker.postMessage(code);

    worker.addEventListener('message', event => {
      resolve(event)
      worker.terminate()
    }, {
      once: true
    })

    worker.addEventListener('error', error => {
      reject(error)
      worker.terminate()
    }, {
      once: true
    })
  })
}

二、手动释放:worker = null

/**
 * 运行js代码
 * @param code js代码
 * @returns {Promise<unknown>}
 */
export function runJs (code) {
  return new Promise((resolve, reject) => {
    let worker = new Worker("worker.js");
    worker.postMessage(code);

    worker.onmessage = (event) => {
      resolve(event)
      worker.terminate()
      worker = null
    };

    worker.onerror = (error) => {
      reject(error)
      worker.terminate()
      worker = null
    }
  })
}

相关推荐

  1. 一个导致内存泄漏问题

    2024-04-21 10:04:02       30 阅读
  2. 前端理论总结(js)——内存泄漏

    2024-04-21 10:04:02       42 阅读
  3. 内存泄漏导致Hard_Fault问题记录

    2024-04-21 10:04:02       43 阅读
  4. (js问题

    2024-04-21 10:04:02       60 阅读
  5. Golang中HTTP内存泄漏

    2024-04-21 10:04:02       30 阅读

最近更新

  1. docker php8.1+nginx base 镜像 dockerfile 配置

    2024-04-21 10:04:02       94 阅读
  2. Could not load dynamic library ‘cudart64_100.dll‘

    2024-04-21 10:04:02       100 阅读
  3. 在Django里面运行非项目文件

    2024-04-21 10:04:02       82 阅读
  4. Python语言-面向对象

    2024-04-21 10:04:02       91 阅读

热门阅读

  1. ResouceUtils.getFile()取不到Jar中资源文件源码

    2024-04-21 10:04:02       27 阅读
  2. 由对极约束得到基础矩阵

    2024-04-21 10:04:02       29 阅读
  3. go 语言 mage 安装踩坑

    2024-04-21 10:04:02       39 阅读