【程序员日记】一行console.log引发的血案

news2024/11/29 8:34:51

▒ 目录 ▒

    • 🛫 导读
      • 需求
      • 开发环境
    • 1️⃣ 艰难的排查过程
      • 1. 程序闪退
      • 2. 确定为内存泄漏
      • 3. 误入歧途
      • 4. 二分法注释代码
      • 5. 猿脑猜想
    • 2️⃣ 排查
      • procexp.exe
      • Performance 和 Memory
    • 3️⃣ 剔除生产环境中的console.log
      • webpack插件terser-webpack-plugin
    • 🛬 文章小结
    • 📖 参考资料

🛫 导读

需求

最近公司使用electron中出现内存泄漏的情况。经过n天的努力,最后定位到console.log的问题。
这好像不是第一次遇到类似的问题,特此记录,以敬后效。

开发环境

版本号描述
文章日期2023-11-04
操作系统Win10 - 22H219045.3570

1️⃣ 艰难的排查过程

1. 程序闪退

开发过程中程序一切运行正常,到了测试那里,出现崩溃情况。
多次尝试发现半个小时左右就崩溃了,多个电脑都是这样的。

2. 确定为内存泄漏

一开始一直以为是自己开发的node模块代码异常,导致崩溃。
后来看了下任务管理器的内存,发现某个render进程内存螺旋式上升,积累到半个小时候就崩溃了。
结论:

  • 内存泄漏导致崩溃
  • 大概率不是node模块导致的,因为是render进程不断的增大。

3. 误入歧途

排查问题最笨的思路就是注释代码。由于各种原因,我们也是这条路排查的。
当我们注释掉某封包逻辑后发现一切运行正常。于是猜测是封包的库导致的问题,当即想的是换个库试试。

4. 二分法注释代码

后来某大佬说,可能是用法不对,逐步注释代码试试。然后二分法注释代码,最后在WebSocket的某回调函数内发现,注释了console.log,让一切恢复正常了。

5. 猿脑猜想

该代码会将接受的内容(3Mb左右的对象)打印出来,最后发现该对象未被释放。至于为何未释放,这里也只留下几个猜想:

  • WebSocket回调函数对该对象进行了引用,导致GC不能释放。
  • WebSocket回调函数对该对象进行了缓存(方便后续调用),缓存队列巨大(上千的长度),chrome内存是有上限的(各个版本不一样的,我们用的x86的,据说在2G左右),达到上限的时候,还未出发其内存回收。

2️⃣ 排查

procexp.exe

作为专业的windows工具procexp.exe,提供了查看内存变换的功能,我们可以通过它看到一些内存上的规律。
小编遇到的问题,可以在这上面发现,每2秒,内存增加3Mb左右。这个大小刚好是我们传递的某个对象,通过它能快速定位问题。

procexp.exe默认没有显示Private Delta Bytes选项,我们通过下面的步骤打开该列。

  1. 右键表头,打开对话框
    在这里插入图片描述
    2.选择Process Memory标签页,然后选择Private Delta Bytes选项
    在这里插入图片描述
  • 模拟内存增长:
    如下图,不断的执行window.___=[]; ___.push(new Array(2*1000*1000));,可以查看到内存增长!
    在这里插入图片描述

ps: windows自带的任务管理器也有类似的功能(貌似win11后的某个新版本才有的)。

Performance 和 Memory

这个操作就很专业了,具体细节很多,小编发现一篇很不错的文章:《console.log 一定会导致内存泄漏? 》https://juejin.cn/post/7185501830040944698,这里就不画蛇添足了,有兴趣的直接看该文章即可。

3️⃣ 剔除生产环境中的console.log

webpack插件terser-webpack-plugin

erser-webpack-plugin 是一个 Webpack 的插件,它主要用于对 JavaScript 代码进行压缩和优化。
它通过使用 Terser 这个 JavaScript 压缩库,来实现对 JavaScript 代码的压缩和优化。Terser 是一个非常强大的压缩库,它能够减小 JavaScript 代码的体积,并提高代码的运行效率。

terser-webpack-plugin 插件的使用非常简单,只需要在 Webpack 的配置中添加这个插件,并设置相关的选项即可。可以进行如下配置,保证生成环境中不包含console系列函数:

module.exports = {
  optimization: {
    minimizer: [
      new TerserPlugin({
        terserOptions: {
          // 你的压缩选项
          compress: {
            // drop_console为true时,将删除所有console的函数
            drop_console: process.env.NODE_ENV==='production',
            drop_debugger: true,
            pure_funcs: ["console.log", "console.warn"]
          }
        }
      }),
    ],
  },
};

🛬 文章小结

首先,我们需要明确一点,console.log 本身并不会造成内存泄漏。内存泄漏是指在程序运行过程中,一些不再需要的对象或资源仍然被占用,导致内存无法被释放,从而导致程序运行缓慢或崩溃。

我们来分析一下可能导致内存泄漏的原因。主要有以下几种可能:

  • 闭包:如果在 console.log 中使用了闭包,并且该闭包中引用了外部的变量或对象,那么这些变量或对象就不会被垃圾回收器回收,从而导致内存泄漏。
  • 对象池:如果在代码中使用了对象池技术,例如Pool 或cache,那么这些对象可能会被长期占用,从而导致内存泄漏。
  • 循环引用:如果在代码中存在两个或多个对象之间的循环引用,例如A引用了B,B引用了A,那么这些对象就不会被垃圾回收器回收,从而导致内存泄漏。

综上所述,console.log 本身并不会造成内存泄漏。但是,如果在代码中使用了不当的闭包、对象池或循环引用,那么这些因素可能会导致内存泄漏。
因此,在编写代码时,我们需要注意避免这些问题,以保证程序的稳定性和性能。而且尽可能的别让 console.log 上生产!

📖 参考资料

  • console.log 一定会导致内存泄漏?不打开 devtools 就不会 https://juejin.cn/post/7185501830040944698
  • 千万别让 console.log 上生产! https://juejin.cn/post/7185128318235541563

ps: 文章中内容仅用于技术交流,请勿用于违规违法行为。

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

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

相关文章

Openlayers--自定义修改天地图颜色

自定义修改地图颜色 前言效果图1、给titleLayer设置className2、给class设置样式 前言 本篇文章讲解怎样调整地图颜色 效果图 调整前 调整后 1、给titleLayer设置className const arcGISLayer new TileLayer({className:blueLayer,//增加className属性source: new XYZ(…

01 向量基本概念

向量基本概念 向量是什么物理专业学生视角计算机专业学生视角数学家视角 不同视角之间的关系 这是关于3Blue1Brown "线性代数的本质"的学习笔记。 向量是什么 物理专业学生视角 向量是空间中的箭头。向量的长度和方向确定一个向量。只要长度和方向相同&#xff0c…

Tcl语言:SDC约束命令create_clock详解

相关阅读 Tcl语言https://blog.csdn.net/weixin_45791458/category_12488978.html?spm1001.2014.3001.5482 在一个设计中创建一个时钟对象的SDC命令是create_clock。该指令的BNF范式(有关BNF范式,可以参考以往文章)为: create_…

一文弄懂synchronized

简述 synchronized是什么? synchronized 关键字是一种同步锁,它可以保证在一个时刻只有一个线程可以执行某段代码。synchronized 关键字可以用在方法、代码块、静态方法和静态代码块上。 synchronized怎么用? synchronized是Java中用于实现线程同步…

最新Ai系统ChatGPT程序源码+以图生图+Dall-E2绘画+支持GPT4+Midjourney绘画

一、AI创作系统 SparkAi创作系统是基于OpenAI很火的ChatGPT进行开发的Ai智能问答系统和Midjourney绘画系统,支持OpenAI-GPT全模型国内AI全模型。本期针对源码系统整体测试下来非常完美,可以说SparkAi是目前国内一款的ChatGPT对接OpenAI软件系统。那么如…

Spring Cloud之Seata的学习

目录 案例准备 分布式事务 基本理论 CAP定理 BASE理论 Seata 部署TC服务 数据库准备 修改Nacos配置并导入信息 启动Seata 集成Seata XA模式原理 Seata的XA实现 优点 缺点 实现 AT模式原理 AT模式的脏写问题 Seata的AT实现 XA与AT的区别 TCC模式原理 空回…

深度学习之基于Python+OpenCV+dlib的考生信息人脸识别系统(GUI界面)

欢迎大家点赞、收藏、关注、评论啦 ,由于篇幅有限,只展示了部分核心代码。 文章目录 一项目简介 二、功能三、系统四. 总结 一项目简介 深度学习在人脸识别领域的应用已经取得了显著的进展。Python是一种常用的编程语言,它提供了许多强大的库…

Python基础入门例程37-NP37 不低于与不超过(运算符)

最近的博文: Python基础入门例程36-NP36 谁的数字大(运算符)-CSDN博客 Python基础入门例程35-NP35 朋友的年龄是否相等(运算符)-CSDN博客 Python基础入门例程34-NP34 除法与取模运算(运算符)…

SpringSecurity全家桶 (二) ——实现原理

1. SpringSecurity的强大之处 当我们并未设置登录页面时,我们只需要导入SpringSecurity的依赖就可以令我们的界面进入保护状态,由下面例子可以凸显出: 随便写个接口 RequestMapping("/hello")public String hello(){return "H…

spring-boot中实现分片上传文件

一、上传文件基本实现 1、前端效果图展示&#xff0c;这里使用element-ui plus来展示样式效果 2、基础代码如下 <template><div><el-uploadref"uploadRef"class"upload-demo":limit"1":on-change"handleExceed":auto-…

PPT制作指南

诸神缄默不语-个人CSDN博文目录 文章目录 1. SOP2. PPT的目标3. PPT素材4. 内容框架5. 设计细节本文撰写过程中使用到的参考资料 1. SOP 分析目标→收集素材→明确框架→视觉呈现 2. PPT的目标 演讲型PPT&#xff1a;字少图多 阅读型PPT&#xff1a;需要文字解释 分析维度&…

shell学习脚本05(小滴课堂)

可以对海量的数据进行提取。 -v对提取的内容进行取反。 -n显示出行号。 -w精确匹配&#xff1a; -i:忽略大小写&#xff1a; -E正则匹配&#xff1a; cut命令&#xff1a; -d指定分隔符&#xff0c;-f指定截取区域&#xff1a; 截取第一列到第三列&#xff1a; 截取第二列到最…

一文带你了解如何让自动化测试框架更自动化

一、引言 ​对于大厂的同学来说&#xff0c;接口自动化是个老生常谈的话题了&#xff0c;毕竟每年的MTSC大会议题都已经能佐证了&#xff0c;不是大数据测试&#xff0c;就是AI测试等等&#xff08;越来越高大上了&#xff09;。不可否认这些专项的方向是质量智能化发展的方向…

第五章 Python文件操作

系列文章目录 第一章 Python 基础知识 第二章 python 字符串处理 第三章 python 数据类型 第四章 python 运算符与流程控制 第五章 python 文件操作 第六章 python 函数 第七章 python 常用内建函数 第八章 python 类(面向对象编程) 第九章 python 异常处理 第十章 python 自定…

SpringBoot框架使用AOP + 自定义注解实现请求日志记录

一、SpringBoot记录日志 文章目录 一、SpringBoot记录日志1.1、环境搭建1.2、配置FastJson1.3、自定义LogRecord注解1.4、定义日志实体类1.5、创建HttpRequestUtil工具类1.6、定义AOP切面1.7、编写测试类1.8、运行测试 1.1、环境搭建 搭建SpringBoot工程。引入【spring-boot-st…

Docker:Dockerfile语法

Docker&#xff1a;Dockerfile语法 1. 镜像2. 镜像结构3. Dockerfile 1. 镜像 前面我们一直在使用别人准备好的镜像&#xff0c;那如果我要部署一个Java项目&#xff0c;把它打包为一个镜像该怎么做呢&#xff1f; 2. 镜像结构 要想自己构建镜像&#xff0c;必须先了解镜像的…

【漏洞复现】IIS_7.o7.5解析漏洞

感谢互联网提供分享知识与智慧&#xff0c;在法治的社会里&#xff0c;请遵守有关法律法规 文章目录 1.1、漏洞描述1.2、漏洞等级1.3、影响版本1.4、漏洞复现1、基础环境2、漏洞扫描3、漏洞验证 1.5、修复建议 1.1、漏洞描述 漏洞原理&#xff1a; cgi.fix_path1 1.png/.php该…

送你几款开源IDC资产管理系统

更多运维技术&#xff0c;请关注微信公众号“运维之美” 送你几款开源IDC资产管理系统 1.phpIPAM2.NetBox3.IPPlan4.GestiIP5.RackTables 对于公司机房运维人员来说&#xff0c;你的idc资产管理清单可能还记录在各种excel表格中&#xff0c;当设备和ip变动的时候进行手动更新&a…

Java继承:抽取相同共性,实现代码复用

&#x1f451;专栏内容&#xff1a;Java⛪个人主页&#xff1a;子夜的星的主页&#x1f495;座右铭&#xff1a;前路未远&#xff0c;步履不停 目录 一、继承的概念二、继承的语法三、父类成员访问1、子类中访问父类成员变量Ⅰ、子类和父类不存在同名成员变量Ⅱ、子类和父类成员…

泄漏检测与修复(LDAR)过程管控平台(销售出租)VOCs便携式总烃分析仪(销售出租)

LDAR是Leak Detection and Repair&#xff08;泄漏检测与修复&#xff09;的缩写&#xff0c;也是国际上较先进的化工废气检测技术。LDAR主要通过检测化工企业原料输送管道、泵、阀门、法兰等易产生易产生挥发性有机物&#xff08;简称VOCs&#xff09;泄漏的部位&#xff0c;并…