当前位置:首页 > 内存 > 正文

js内存泄露分享PPT(js内存泄漏情况)

  • 内存
  • 2024-08-13 22:05:29
  • 8537

一、javascriptsetTimeout递归会造成内存泄漏吗前端开发,热爱生活
varcall=function(x){
(x++);
setTimeout(function(){call(x);},1);
};
call(0);
以这段代码为例确实,变量x会一直存在于内存中,但是这样的变量不会导致内存溢出
出来。并且可以在chromeDevTool中模拟垃圾回收的结果:
可以看到jsheap增加了。可以看到jsheap增加了。
但是控制台仍然存在内存泄漏。但控制台仍然运行,这实际上是内存泄漏。
如果内存有规律地增长,泄漏最终会导致浏览器变慢或停止执行脚本。从性能优化的角度来看,这已经是要做的事情了。我认为如果循环中执行的代码包含一大堆newArray(1000000).join('*'),那将是非常危险的。
一般setTimeout递归是轮询,需要超时条件和clearTimeout的执行。
二、内存泄漏是什么以及如何解决
内存泄漏是指当一个对象效率低下,需要回收,但由于另一个对象引用它而无法被回收,而残留在堆内存中时,这称为内存泄漏。最常见的包括意外的全局变量、DOM泄漏和循环引用
[推荐课程:JavaScript教程]
内存泄漏

内存泄漏一般是指对象没有任何作用,必须被回收的情况此时,另一个正在使用的对象由于引用了该对象而无法被回收。这个无法回收的对象保留在堆内存中,造成内存泄漏。
当一个对象不再需要需要回收时,另一个正在使用的对象包含了对它的引用,这就阻止了它回收该对象需要回收的对象保留在堆内存中,这就产生了内存泄漏
常见的内存泄漏:
1.意外的全局变量
JS处理未定义变量的方式:未定义的变量会在浏览器的全局对象中创建一个新的变量,该全局对象是window。
functionfoo(arg){
bar="thisisahiddenglobalvariable";//相当于="thisisahiddenglobalvariable"
2="potialaccidentalglobal";//this指向这里的对象global(window),
相当于2="potialaccidentalglobal"}解决方案:在JavaScript程序中添加并启用严格模式'usestrict',可以有效避免上述问题。
注意:用于临时存储大量数据的全局变量应设置为空或在验证数据处理完毕后重新赋值。
2。DOMLeak
在浏览器中,DOM和JS使用的引擎不同,都使用渲染引擎,而JS使用v8引擎,所以当使用JS让DOM工作时,就会有一个。比较。这会消耗性能,因此为了减少DOM操作,我们会使用变量引用将它们缓存在当前环境中。如果执行某些删除或更新操作,您可能会忘记释放缓存的DOM,从而导致内存泄漏
示例:引用尚未清理的DOM元素
varrefA=mentById('refA');
Child(refA);//#refA无法回收,因为refA变量中有对它的引用。
删除对#refA的引用,但#refA仍然不可回收。解决办法:设置refA=null;
3.忘记定时器和回调函数
varsomeResource=getData();
setInterval(function(){
varnode=mentById('Node');
if(node){
TML=ify(someResource));
}
},1000);这样的代码很常见,如果具有节点ID的元素从DOM中删除,计时器仍然存在。同时,由于回调函数中包含了someResource的引用,定时器之外的someResource不会被释放
4.在js内存管理环境中,如果对象A有权限访问对象B,则称对象A引用了对象B。引用计数策略是看该对象是否有其他对象引用它。如果没有对象引用该对象,那么该对象将被回收。
varobj1={a:1};//创建一个对象(称为A)并赋值给obj1。A的引用次数为1
varobj2=obj1;//A的引用次数变为2
obj1=0;//A的引用次数变为1
obj2=0;//A的引用次数变成0,此时可以取出对象A了。但引用计数的最大问题是循环引用。
functionfunc(){
varobj1={};
varobj2={};
obj1.a=obj2;//obj1引用obj2
obj2.a=obj1;//obj2引用obj1}当函数执行结束时,返回值未定义,因此整个函数和内部变量都需要回收,但根据引用计数方法,obj1和obj2的引用计数不为0。,因此它们不会被回收。所以要解决这个问题可以将它们的值设置为null
总结: