react 内存泄露常见问题解决方案 墨蓝 2022-10-01 09:53 410阅读 0赞 ## 写在前面 ## * 在写 react 代码的时候经常遇到如下的报错 Can't perform a React state update on an unmounted component. This is a no-op...... 复制代码 * 本篇文章首先回顾一下什么是内存泄露,然后看两个 demo 观察 react 出现内存泄露的具体情况。 ## 什么是内存泄露 ## * 程序的运行需要内存。只要程序提出要求,操作系统或者运行时(runtime)就必须供给内存。 * 对于持续运行的服务进程(daemon),必须及时释放不再用到的内存。否则,内存占用越来越高,轻则影响系统性能,重则导致进程崩溃。 * 不再用到的内存,没有及时释放,就叫做内存泄漏(memory leak)。 ## JavaScript 中常见的几种内存泄露 ## * 全局变量引起的内存泄漏 function leaks(){ leak = '***'; //leak 成为一个全局变量,不会被回收 } 复制代码 * 闭包引起的内存泄漏 var leaks = (function(){ var leak = '***';// 被闭包所引用,不会被回收 return function(){ console.log(leak); } })() 复制代码 * dom清空或删除时,事件未清除导致的内存泄漏 document.querySelector("#demo").addEventListener('click', myFunction); var para1=document.querySelector("#demo"); para1.parentNode.removeChild(para1); 复制代码 > 如果我们在没有取消 click 方法前去销毁了 para1 节点,就会造成内存泄露。 **正确的做法:** document.querySelector("#demo").addEventListener('click', myFunction); // 我们需要在删除节点前清除挂载的 click 方法 document.querySelector("#demo").removeEventListener("click", myFunction); var para1=document.querySelector("p1"); para1.parentNode.removeChild(para1); 复制代码 * 延展阅读,大家有空可以仔细的看看阮一峰老师的相关文章 * [www.ruanyifeng.com/blog/2017/0…][www.ruanyifeng.com_blog_2017_0] (阮一峰) ## 为了更加了解 react 的内存泄露问题看看下面几个 demo ## ### Demo 1: ### componentWillMount: function () { var onLogin = this.props.onLogin || function () {}, onLogout = this.props.onLogout || function () {}; this.on('authChange', function () { console.log('user authenticated:', this.state.isAuthenticated); return this.state.isAuthenticated ? onLogin(this.state) : onLogout(this.state); }.bind(this)); }, 复制代码 * 上面的例子是在 Stack Overflow 上看到的,楼主在`componentWillMount`的时候挂载了`authChange`事件,然后 react 出现了如下的报错: **Can't perform a React state update on an unmounted component. This is a no-op, but it indicates a memory leak in your application. To fix, cancel all subscriptions and asynchronous tasks in the componentWillUnmount method”** * 意思为:我们不能在组件销毁后设置state,防止出现内存泄漏的情况 ### 需要怎么解决啦? ### * 添加如下代码即可 componentWillUnmount: function () { this.off('authChange', this.authChange); this.authChange = null; } 复制代码 > 很明显这种情况就是在 dom 结构销毁的时候,事件却没有清除导致的内存泄漏,所以我们需要在`componentWillUnmount`的时候去清除挂载的方法 ### *react 内存泄露相关解释和解决方法* ### * 这里就提到了内存泄露,当我们在使用事件绑定,setInterval,setTimeOut 或一些函数的时候,但是却没有在组件销毁前清除的时候会造成内存泄露。这里我们手动的再`componentWillUnmount`去清除相关的方法即可。 * why: * I would move your function into componentDidMount and add cleanup on componentWillUnmount * Important: componentWillMount is called on the server and client, but componentDidMount is only called on the client. * If you’re using eventListeners, setInterval or other functions that needs to be cleaned, put them in componentDidMount. The server will not call componentWillUnmount and is usually the cause of memory leaks. * [stackoverflow.com/questions/4…][stackoverflow.com_questions_4] ### Demo 2: ### * 下面这种就是常见的情况: this.pwdErrorTimer = setTimeout(() => { this.setState({ showPwdError:false }) }, 1000); 复制代码 设置了一个timer延迟设置state,然而在延迟的这段时间,组件已经销毁,则造成此类问题 * 解决方法: * 利用生命周期钩子函数:componentWillUnmount componentWillUnmount(){ clearTimeout(this.pwdErrorTimer); clearTimeout(this.userNameErrorTimer); } 复制代码 ## 衍生阅读 ## ### 关于 promise 请求是否会造成内存泄露的问题 ### #### 1、Does never resolved promise cause memory leak? #### * [Does never resolved promise cause memory leak?][Does never resolved promise cause memory leak] * 原问题在上面,可以看看 #### 2、Memory leaks in loops with Promise ? #### * [循环一个 promise 造成内存泄露? ][promise _] 转载于:https://juejin.im/post/5ca48a136fb9a05e6c77bd9a [www.ruanyifeng.com_blog_2017_0]: https://link.juejin.im?target=http%3A%2F%2Fwww.ruanyifeng.com%2Fblog%2F2017%2F04%2Fmemory-leak.html [stackoverflow.com_questions_4]: https://link.juejin.im?target=https%3A%2F%2Fstackoverflow.com%2Fquestions%2F40159756%2Freact-component-with-memory-leak [Does never resolved promise cause memory leak]: https://link.juejin.im?target=https%3A%2F%2Fstackoverflow.com%2Fquestions%2F20068467%2Fdoes-never-resolved-promise-cause-memory-leak [promise _]: https://link.juejin.im?target=https%3A%2F%2Fwww.v2ex.com%2Ft%2F287602
相关 理解Java内存泄露问题及解决方案 在Java编程中,内存泄露是一个常见的问题。简单来说,内存泄露是指程序在申请内存后,无法释放已申请的内存空间,导致系统可用内存持续减少。 解决Java内存泄露的方法如下: 悠悠/ 2024年09月17日 20:15/ 0 赞/ 8 阅读
相关 Java中的内存泄露问题及解决方案 在Java编程中,内存泄露是一个常见的问题。简单来说,内存泄露是指程序无法释放已申请但不再使用的内存空间。 解决Java内存泄露问题的方法主要包括以下几个方面: 1. ** Bertha 。/ 2024年09月12日 19:06/ 0 赞/ 15 阅读
相关 Java内存泄露示例及解决方案 在Java中,内存泄露通常是指程序申请了内存空间,但在适当的时候没有释放这些内存,导致系统可用的内存越来越少。 下面是一个简单的内存泄露示例: ```java class 本是古典 何须时尚/ 2024年09月12日 04:15/ 0 赞/ 24 阅读
相关 Java中常见内存泄露问题实例 在Java中,内存泄露通常是由于资源未能正确释放导致的。以下是一些常见的内存泄露问题实例: 1. **同步阻塞循环**: ```java class Resour 缺乏、安全感/ 2024年09月10日 06:12/ 0 赞/ 21 阅读
相关 Java中内存泄露问题及解决方案实例 在Java编程中,内存泄露是一个常见的问题。内存泄露是指程序在申请内存后,无法释放已申请的内存空间,导致系统可用内存越来越少。 以下是一些关于内存泄露问题及解决方案的实例: ╰+攻爆jí腚メ/ 2024年09月10日 02:33/ 0 赞/ 22 阅读
相关 Java中常见内存泄露问题 在Java编程中,常见的内存泄露问题包括: 1. 引用循环:当两个对象相互引用(如一个对象的字段是另一个对象的引用),而这些引用没有被妥善处理时,就会形成循环引用,导致内存无 ╰+攻爆jí腚メ/ 2024年09月05日 22:42/ 0 赞/ 16 阅读
相关 react 内存泄露常见问题解决方案 写在前面 在写 react 代码的时候经常遇到如下的报错 Can't perform a React state update on an unmount 墨蓝/ 2022年10月01日 09:53/ 0 赞/ 411 阅读
相关 一个常见的android内存泄露 问题 最近在公司看一个算比较大的android项目的源码,发现了一个很严重的问题,就是项目里使用单例模式,构造函数要传入Context做参数的类,基本上都存在内存泄露问题。我想这 亦凉/ 2022年07月28日 01:15/ 0 赞/ 150 阅读
还没有评论,来说两句吧...