js内存泄露

news/2024/7/19 15:26:34 标签: js

文章目录

  • 定义
  • 引起内存泄漏的操作
    • Chrome 控制台查看内存情况
      • 无痕模式
      • Performance
      • Memotry
        • 1. 先用 Allocation instrumentation on timeline 确认问题
        • 2. 再用 Head snapshot 定位代码
    • 闭包函数使用不当
    • 全局变量
    • 分离的DOM节点
    • 控制台的打印
  • 避免策略

js内存泄露如何检测?场景有哪些?如何定位到具体代码?

定义

程序中已动态分配的堆内存由于某种原因程序未释放或无法释放引发的各种问题,如浏览器变慢,奔溃,延迟大

引起内存泄漏的操作

  1. 闭包函数使用不当
  2. 未使用的 var 声明的全局变量
  3. 分离的DOM节点
  4. 控制台日志(console.log)
  5. 遗忘定时器

Chrome 控制台查看内存情况

无痕模式

打开Chrome的无痕模式,这样做的目的是为了屏蔽掉Chrome插件对我们之后测试内存占用情况的影响

Performance

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

在页面从零到加载完成这个过程中JS Heapjs堆内存)、documents(文档)、Nodes(DOM节点)、Listeners(监听器)、GPU memory(GPU内存)的最低值、最高值以及随时间的走势曲线

Memotry

作用:用于记录页面堆内存的具体情况以及js堆内存随加载时间线动态的分配情况
在这里插入图片描述

1. 先用 Allocation instrumentation on timeline 确认问题

在这里插入图片描述

在开始记录后,我们可以看到图中右上角有起伏的蓝色与灰色的柱形图,其中蓝色表示当前时间线下占用着的内存;灰色表示之前占用的内存空间已被清除释放

2. 再用 Head snapshot 定位代码

闭包函数使用不当

// 其中,arr被赋值给 res,arr 被标记为活动变量并一直占用着相应的内存,假如 res 后续用不到,这内存就一直占用 
<button onclick="btnClick()">点击</button>
<script>
    function test() {
        let arr = new Array(1000000);// 一个很大的数组对象
        function fn() {
            let c = [1, 2, 3]
        }
        fn()
        return arr
    }
    let res = []
    function btnClick() {
        res.push(test())
    }
</script>
  1. 先使用 performacne 的曲线图
    在这里插入图片描述
    在这里插入图片描述

在每次录制开始时手动触发一次垃圾回收机制,这是为了确认一个初始的堆内存基准线,便于后面的对比,然后我们点击了几次按钮,即往全局数组变量res中添加了几个比较大的数组对象,最后再触发一次垃圾回收,发现录制结果的JS Heap曲线刚开始成阶梯式上升的,最后的曲线的高度比基准线要高,说明可能是存在内存泄漏的问题

  1. 用 Allocation instrumentation on timeline 手机动态内存分配情况
    在这里插入图片描述

动态内存分配情况图上都会出现一个蓝色的柱形,并且在我们触发垃圾回收后,蓝色柱形都没变成灰色柱形,即之前分配的内存并未被清除,确认内存泄漏的问题是存在的

  1. 用 Head snapshot 定位
    在这里插入图片描述
    在这里插入图片描述

所以选择Object allocated between Snapshot1 and Snapshot2即展示第一条快照和第二条快照存在差异的内存对象分配情况,Array的百分比很高,初步可以判断是该变量存在问题

全局变量

全局变量的内存空间一直不会被释放

分离的DOM节点

<div id="root">
    <div class="child">我是子元素</div>
    <button>移除</button>
</div>
<script>
    let btn = document.querySelector('button')
    let child = document.querySelector('.child')
    let root = document.querySelector('#root')

    btn.addEventListener('click', function () {
        root.removeChild(child)
    })
</script>

在这里插入图片描述

在这里插入图片描述

点击按钮后移除.child的节点,虽然点击后,该节点确实从dom被移除了,但全局变量child仍对该节点有引用,所以导致该节点的内存一直无法被释放

控制台的打印

<button>按钮</button>
<script>
    document.querySelector('button').addEventListener('click', function () {
        let obj = new Array(1000000)

        console.log(obj);
    })
</script>

在这里插入图片描述

先触发一次垃圾回收清除初始的内存,然后点击三次按钮,即执行了三次点击事件,最后再触发一次垃圾回收。查看录制结果发现JS Heap曲线成阶梯上升,并且最终保持的高度比初始基准线高很多,这说明每次执行点击事件创建的很大的数组对象obj都因为console.log被浏览器保存了下来并且无法被回收

避免策略

  1. 减少不必要的全局变量
  2. 避免"死循环"
  3. 避免创建过多的对象
  4. 减少层级过多的引用
  5. 避免定时器遗忘

http://www.niftyadmin.cn/n/338597.html

相关文章

如何把ipa文件(iOS安装包)安装到iPhone手机上? 附方法汇总

苹果APP安装包ipa如何安装在手机上&#xff1f;很多人不知道怎么把ipa文件安装到手机上&#xff0c;这里就整理了苹果APP安装到iOS设备上的方式&#xff0c;仅供参考 苹果APP安装包ipa如何安装在手机上&#xff1f;使用过苹果手机的人应该深有感触&#xff0c;那就是苹果APP安…

【程序员面试金典】面试题 05.03. 翻转数位

【程序员面试金典】面试题 05.03. 翻转数位 题目描述解题思路 题目描述 描述&#xff1a;给定一个32位整数 num&#xff0c;你可以将一个数位从0变为1。请编写一个程序&#xff0c;找出你能够获得的最长的一串1的长度。 输入: num 1775(110111011112) 输出: 8输入: num 7(0…

javaIO流之字节流

目录 1、字节输出流&#xff08;OutputStream&#xff09;2、FileOutputStream类2.1FileOutputStrea 的构造方法2.2FileOutputStream 写入字节数据2.3FileOutputStream实现数据追加、换行 3、字节流入流&#xff08;InputStream&#xff09;4、FileInputStream类4.1FileInputSt…

Midjourney基础教程

本教程收集于:AIGC从入门到精通教程 Midjourney基础教程 目录 新手快速入门知识汇总:

物联网通信协议及应用场景

物联网通信协议 ZigBeeLoRaSigfoxWi-FiBluetoothRFIDZ-WaveThread6LoWPANNarrowband IoT (NB-IoT)的前身2G和3G网络 这些技术和协议都有其独特的特点和应用场景&#xff0c;可以根据具体的需求来选择使用哪种技术。物联网传输除了传感器还有许多其他产品&#xff0c;例如嵌入式…

一个招聘网站的详细部件设计

目 录 三、详细设计报告.................................................. 1 1引言.................................................................... 1 2 支撑环境............................................................ 1 3 部件详细设计 *.............…

公式编辑器怎么下载?一分钟解决

公式编辑器是一种专门用于编辑和排版数学公式的软件&#xff0c;其主要作用是帮助用户快速、准确地输入数学公式&#xff0c;并将其排版成符合数学规范的形式。数学公式编辑器通常提供了丰富的数学符号和函数库&#xff0c;用户可以通过简单的操作就能够实现复杂的数学公式。 在…

sentinel规则持久化

Sentinel 规则持久化 一、修改order-service服务 修改OrderService&#xff0c;让其监听Nacos中的sentinel规则配置。 具体步骤如下&#xff1a; 1.引入依赖 在order-service中引入sentinel监听nacos的依赖&#xff1a; <dependency><groupId>com.alibaba.cs…