前端开发时的内存泄漏问题

news2025/4/5 14:04:38

目录

    • 🔍 什么是内存泄漏(Memory Leak)?
    • 🚨 常见的内存泄漏场景
      • 1️⃣ 未清除的定时器(setInterval / setTimeout)
      • 2️⃣ 全局变量(变量未正确释放)
      • 3️⃣ 事件监听未清除
      • 4️⃣ 闭包导致的内存泄漏
      • 5️⃣ DOM 引用未释放
    • 🛠 如何检测和防止内存泄漏?
      • 1️⃣ 使用 Chrome DevTools 监测内存
      • 2️⃣ 使用 `WeakMap` 和 `WeakSet`
      • 3️⃣ 确保在 `useEffect` 里清理副作用(React)
    • ✅ 总结

🔍 什么是内存泄漏(Memory Leak)?

内存泄漏 指的是 程序运行时,已经不再使用的内存无法被释放,导致内存占用不断增加,最终可能会导致应用性能下降甚至崩溃。

在 JavaScript 中,垃圾回收机制(GC, Garbage Collection) 会自动释放不再使用的变量,但某些情况下,对象仍然被错误地引用,导致 GC 无法回收,从而造成内存泄漏。


🚨 常见的内存泄漏场景

1️⃣ 未清除的定时器(setInterval / setTimeout)

当使用 setIntervalsetTimeout 时,如果不手动清除,函数的引用会一直保留,导致内存泄漏。

function startTimer() {
  setInterval(() => {
    console.log("Running...");
  }, 1000);
}
// 调用后,即使不再需要,定时器仍然占用内存
startTimer();

解决方法:在组件销毁或不需要时清除定时器

const timer = setInterval(() => {
  console.log("Running...");
}, 1000);

clearInterval(timer); // 及时清除定时器

2️⃣ 全局变量(变量未正确释放)

如果一个变量被赋值到 window 或全局作用域,它将一直存在,导致内存无法被回收。

window.leak = []; // 这个数组永远不会被回收

解决方法:避免在 window 作用域创建变量

(function() {
  let tempArray = [];
})();

3️⃣ 事件监听未清除

当事件监听器(如 addEventListener)绑定到 DOM 元素上,但该元素被移除时,监听器仍然存在,导致 JavaScript 引用无法被释放。

document.getElementById("btn").addEventListener("click", function() {
  console.log("Clicked!");
});

解决方法:组件卸载时移除监听

const btn = document.getElementById("btn");
const handleClick = () => console.log("Clicked!");
btn.addEventListener("click", handleClick);

// 在适当时机移除监听器
btn.removeEventListener("click", handleClick);

4️⃣ 闭包导致的内存泄漏

闭包 使得内部函数可以访问外部函数的变量,但如果变量一直被引用,GC 无法释放它。

function createClosure() {
  let data = new Array(1000000); // 大量数据
  return function () {
    console.log(data.length);
  };
}

const closure = createClosure();
// `data` 变量不会被释放

解决方法:在不需要时手动清空变量

let closure = createClosure();
closure = null; // 解除引用,让 GC 回收

5️⃣ DOM 引用未释放

如果 JavaScript 变量仍然引用一个已删除的 DOM 元素,该元素不会被回收。

let div = document.getElementById("myDiv");
document.body.removeChild(div); // 移除 DOM
// 但 div 变量仍然持有该元素的引用,导致泄漏

解决方法:手动释放引用

div = null; // 解除 JavaScript 引用,让 GC 处理

🛠 如何检测和防止内存泄漏?

1️⃣ 使用 Chrome DevTools 监测内存

  • 打开 Performance 面板录制检查内存占用
  • Memory 面板 中使用 Heap Snapshot,查看哪些对象未被释放。

2️⃣ 使用 WeakMapWeakSet

  • WeakMapWeakSet 不会阻止垃圾回收,适用于临时数据存储。
let weakMap = new WeakMap();
let obj = { key: "value" };
weakMap.set(obj, "some data");
obj = null; // `obj` 被回收,WeakMap 也自动释放它的引用

3️⃣ 确保在 useEffect 里清理副作用(React)

如果在 React 组件中添加 事件监听、定时器 等,一定要在 useEffect 里清理:

useEffect(() => {
  const interval = setInterval(() => {
    console.log("Running...");
  }, 1000);

  return () => clearInterval(interval); // 组件卸载时清除定时器
}, []);

✅ 总结

  • 内存泄漏 = 无用的对象无法被 GC 释放,导致内存占用持续增长
  • 常见原因:未清理 定时器、事件监听、闭包、DOM 引用、全局变量
  • 如何避免?
    • 清除定时器和事件监听 (clearInterval, removeEventListener)
    • 避免不必要的全局变量
    • 正确管理闭包(在不需要时清空变量)
    • 使用 Chrome DevTools 检查内存泄漏
    • 在 React 组件中使用 useEffect 清理副作用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2327616.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【Feign】⭐️使用 openFeign 时传递 MultipartFile 类型的参数参考

💥💥✈️✈️欢迎阅读本文章❤️❤️💥💥 🏆本篇文章阅读大约耗时三分钟。 ⛳️motto:不积跬步、无以千里 📋📋📋本文目录如下:🎁🎁&a…

Linux中动静态库的制作

1.什么是库 库是写好的现有的,成熟的,可以复⽤的代码。现实中每个程序都要依赖很多基础的底层库,不可能每个⼈的代码都从零开始,因此库的存在意义非同寻常。 本质上来说库是⼀种可执⾏代码的⼆进制形式,可以被操作系统…

forms实现连连看

说明: forms实现连连看 效果图: step1:C:\Users\wangrusheng\RiderProjects\WinFormsApp2\WinFormsApp2\Form1.cs using System; using System.Collections.Generic; using System.Drawing; using System.Linq; using System.Windows.Forms;namespace …

鸿蒙开发踩坑记录 - 2024S2

wrapBuilder如果想View和ObservedV2做绑定 必须要用 ComponentV2 Param 和 区别 退出两层循环 Builder的传入的参数及时是Trace修饰的也无法刷新组件 折叠屏展开后键盘无法点击 vm是公用的,组件生命周期问题导致 监听键盘高度变化失效 原因:分享面…

0基础入门scrapy 框架,获取豆瓣top250存入mysql

一、基础教程 创建项目命令 scrapy startproject mySpider --项目名称 创建爬虫文件 scrapy genspider itcast "itcast.cn" --自动生成 itcast.py 文件 爬虫名称 爬虫网址 运行爬虫 scrapy crawl baidu(爬虫名) 使用终端运行太麻烦了,而且…

鸿蒙NEXT小游戏开发:井字棋

1. 引言 井字棋是一款经典的两人对战游戏,简单易懂,适合各个年龄段的玩家。本文将介绍如何使用鸿蒙NEXT框架开发一个井字棋游戏,涵盖游戏逻辑、界面设计及AI对战功能。 2. 开发环境准备 电脑系统:windows 10 开发工具:…

deep-sync开源程序插件导出您的 DeepSeek 与 public 聊天

一、软件介绍 文末提供下载 deep-sync开源程序插件导出您的 DeepSeek 与 public 聊天,这是一个浏览器扩展,它允许用户公开、私下分享他们的聊天对话,并使用密码或过期链接来增强 Deepseek Web UI。该扩展程序在 Deepseek 界面中添加了一个 “…

4. 理解Prompt Engineering:如何让模型听懂你的需求

引言:当模型变成“实习生” 想象一下,你新招的实习生总把“帮我写份报告”理解为“做PPT”或“整理数据表”——这正是开发者与大模型对话的日常困境。某金融公司优化提示词后,合同审查准确率从72%飙升至94%。本文将用3个核心法则+5个行业案例,教你用Prompt Engineering让…

网络编程—网络概念

目录 1 网络分类 1.1 局域网 1.2 广域网 2 常见网络概念 2.1 交换机 2.2 路由器 2.3 集线器 2.4 IP地址 2.5 端口号 2.6 协议 3 网络协议模型 3.1 OSI七层模型 3.2 TCP/IP五层模型 3.3 每层中常见的协议和作用 3.3.1 应用层 3.3.2 传输层 3.3.3 网络层 3.3.4…

SELinux

一、selinux技术详解 SELinux 概述 SELinux,即 Security-Enhanced Linux,意为安全强化的 Linux,由美国国家安全局(NSA)主导开发。开发初衷是防止系统资源被误用。在 Linux 系统中,系统资源的访问均通过程…

ES6对函数参数的新设计

ES6 对函数参数进行了新的设计,主要添加了默认参数、不定参数和扩展参数: 不定参数和扩展参数可以认为恰好是相反的两个模式,不定参数是使用数组来表示多个参数,扩展参数则是将多个参数映射到一个数组。 需要注意:不定…

LLaMA Factory微调后的大模型在vLLM框架中对齐对话模版

LLaMA Factory微调后的大模型Chat对话效果,与该模型使用vLLM推理架构中的对话效果,可能会出现不一致的情况。 下图是LLaMA Factory中的Chat的对话 下图是vLLM中的对话效果。 模型回答不稳定:有一半是对的,有一半是无关的。 1、未…

群体智能优化算法-鹈鹕优化算法(Pelican Optimization Algorithm, POA,含Matlab源代码)

摘要 鹈鹕优化算法(Pelican Optimization Algorithm, POA)是一种灵感来自自然界鹈鹕觅食行为的元启发式优化算法。POA 模拟鹈鹕捕食的两个主要阶段:探索阶段和开发阶段。通过模拟鹈鹕追捕猎物的动态行为,该算法在全局探索和局部开…

在 Blazor 中使用 Chart.js 快速创建数据可视化图表

前言 BlazorChartjs 是一个在 Blazor 中使用 Chart.js 的库(支持Blazor WebAssembly和Blazor Server两种模式),它提供了简单易用的组件来帮助开发者快速集成数据可视化图表到他们的 Blazor 应用程序中。本文我们将一起来学习一下在 Blazor 中…

SQL server 2022和SSMS的使用案例1

一,案例讲解 二,实战讲解 实战环境 你需要确保你已经安装完成SQL Server 2022 和SSMS 20.2 管理面板。点此跳转至安装教程 SQL Server2022Windows11 专业工作站SSMS20.2 1,连接数据库 打开SSMS,连接数据库。 正常连接示意图&…

GO语言学习(14)GO并发编程

目录 🌈前言 1.goroutine🌟 2.GMP模型🌟 2.1 GMP的由来☀️ 2.2 什么是GMP☀️ 3.channel 🌟 3.1 通道声明与数据传输💥 3.2 通道关闭 💥 3.3 通道遍历 💥 3.4 Select语句 &#x1f4…

【Audio开发二】Android原生音量曲线调整说明

一,客制化需求 客户方对于音量加减键从静音到最大音量十五个档位区域的音量变化趋势有定制化需求。 二,音量曲线调试流程 Android根据不同的音频流类型定义不同的曲线,曲线文件存放在/vendor/etc/audio_policy_volumes.xml或者default_volu…

spring-security原理与应用系列:HttpSecurity.filters

目录 AnyRequestMatcher WebSecurityConfig HttpSecurity AbstractInterceptUrlConfigurer AbstractAuthenticationProcessingFilter 类图 在前面的文章《spring-security原理与应用系列:securityFilterChainBuilders》中,我们遗留了一个问题&…

JVM生产环境问题定位与解决实战(六):总结篇——问题定位思路与工具选择策略

本文已收录于《JVM生产环境问题定位与解决实战》专栏,完整系列见文末目录 引言 在前五篇文章中,我们深入探讨了JVM生产环境问题定位与解决的实战技巧,从基础的jps、jmap、jstat、jstack、jcmd等工具,到JConsole、VisualVM、MAT的…

并行治理机制对比:Polkadot、Ethereum 与 NEAR

治理是任何去中心化网络的基础。它塑造了社区如何发展、如何为创新提供资金、如何应对挑战以及如何随着时间的推移建立信任。随着 Web3 的不断发展,决定这些生态系统如何做出决策的治理模型也在不断发展。 在最近的一集的【The Decentralized Mic】中, Polkadot 汇…