javascript中导致内存泄漏的行为
1.全局变量
全局变量
2段测试代码
<script> var a = (new Array(1000000).fill("*aaaa1111")); </script> <script> function name() { var a = (new Array(1000000).fill("*aaaa1111")); } </script>
上面一段代码是全局变量,下面一段代码是局部变量
在浏览器自动回收垃圾以后,可以看到第二种写法,会占用比下面更多的内存空间。因为a是全局变量,并没有被释放掉,所以一直留在内存里面。function函数里面的变量在执行完毕以后会释放掉,
不会留在内存中。可以多加几个变量测试一下。
<script> function name() { a = (new Array(1000000).fill("*aaaa1111")); } name(); </script>
这样写变量也不会被释放,不加申明的变量都是全局变量
解决办法,用完就释放
而且我发现,全局变量,手动垃圾回收也是无法被释放的。会一直留在内存里面。
立即执行函数也可以处理这个全局变量导致内存泄漏的问题。
2.不要写console.log()
<script> var setDom = document.getElementById('set'); setDom.addEventListener('click', function(){ console.log(new Array(100000).fill('aaaa1')); }); </script> <script> var setDom = document.getElementById('set'); setDom.addEventListener('click', function(){ }); </script>
2段代码,上面打印值,下面什么都不打印,查看内存的情况,都点击几次div,然后手动垃圾回收,查看结果
可以看出来,console.log的内存也会存在在内存里面,多次点击,甚至会堆起来,手动释放以后,值也还是比没用console.log的高不少。
3.setInterVal
只有interval内的引用被保存在外部,才会造成泄漏,否则,内部的值是会被清除的。但是setInterVal,本身对内存的消耗就不小。
下面这种情况,页面开的时间长一点,占用内存超过1024mb的时候,页面很快就会崩溃的
4.闭包
闭包引起的闭包内的变量无法被释放掉。一直被外部变量引用着,外部变量一直在内存里面,1的情况已经说了,全局变量是无法被释放掉的。
<script> function outer() { var a = (new Array(1000000).fill("*aaaa1111")); var inner = function () { console.info(a) } return inner // inner 就是一个闭包函数,因为他能够访问到outer函数的作用域 } var c = outer(); c(); </script> <script> function outer() { var a = (new Array(1000000).fill("*aaaa1111")); var inner = function () { console.info(a) } return inner // inner 就是一个闭包函数,因为他能够访问到outer函数的作用域 } outer(); </script>
闭包被保存在了全局变量c上面,值并不会被释放掉,所以闭包里面的值一直被存放在内存里面,无法被释放掉。
a.和c都无法被释放了,所以垃圾回收以后内存存储的值更大了,可以试一试console.log(a),最后值还是5662304左右,说明闭包被引用的值才会被储存起来。不引用的值就不会被保存在内存里面
上面是对闭包的解决办法,引用的值,置空,置空以后。内存就自动释放这部分变量了。手动垃圾回收以后,
值就会变成1662300,一下就变小了。一个两个对象放在全局其实不会有问题,但是对象的值特别大,且很多,就会页面奔溃了。
4.对页面的刷新并不能释放泄漏的内存
可以看到不停的刷新页面,内存在不停的增加,但是垃圾回收以后,内存值变小了。
嵌套iframe测试
<head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> <iframe id="iframes" src="./1.html"></iframe> </body> <script> var iframe = document.getElementById('iframes'); document.addEventListener('click', function(){ iframe.src = './1.html?name=222'; console.log('执行了'); }); </script>
频繁刷新iframe也能导致占用内存的变大,手动垃圾回收也能减小内存。cpu的占用也会突然变高。但是我觉得这部分变大对性能的影响不是很大,因为很快变量就被释放掉了,垃圾自动回收2-3秒执行一次,如果内存已经被占用很多可能会有崩溃的可能。