浏览器的内存泄漏(memory leak)问题
1 什么是内存泄漏?
内存泄漏是指内存资源得不到释放 && 失去对该内存区的指针 => 无法复用内存资源,最终导致内存溢出。
2 JS中可以操作的对象有哪些?
Script中我们能操作的对象可分为三种:JS EngineObject、DOM Element 和 BOM Element。
//JSEngine Object: var obj = Object(); var array = []; //DOMElement: var el = document.createElement('div'); var div = document.getElementById('name'); //BOMElement: window; window.location;
其中只有JS Engine Object和DOM Element是我们可以CRUD的,因此也就有可能发生内存泄漏的问题。
3 JS Engine Object & DOM Element的内存回收机制
JSEngine Object 的回收机制:IE的JScriptGarbage Collector采用的是Mark-and-Sweep(标记清除)算法,当执行垃圾回收时会先遍历所有JS Engine Object并标记未被引用的对象,然后释放掉被标记的内存空间。由于Mark-and-Sweep算法的缘故,也能很好地释放引用孤岛的内存空间。而IE下独有的CollectGarbage()则用于回收无引用或引用孤岛的JS Engine Object。
DOMElement的内存回收机制:当DOM Element不再被引用时会被回收。
4 常见的泄露原因
1.循环引用 (跨页面内存泄漏)
2.闭包泄漏 (跨页面内存泄漏)
5 解决工具(内存泄漏的识别方法)
1.Chrome 浏览器查看内存占用
打开开发者工具,选择 Timeline(Performance) 面板
在顶部的Capture字段里面勾选 Memory
点击左上角的录制按钮。
在页面上进行各种操作,模拟用户的使用情况。
一段时间后,点击对话框的 stop 按钮,面板上就会显示这段时间的内存占用情况。
内存占用平稳说明不存在内存泄漏问题。
2.命令行可以使用 Node 提供的process.memoryUsage方法。返回一个对象,包含了 Node 进程的内存占用信息。该对象包含四个字段,单位是字节
rss(resident set size):所有内存占用,包括指令区和堆栈。
heapTotal:"堆"占用的内存,包括用到的和没用到的。
heapUsed:用到的堆的部分。
external: V8 引擎内部的 C++ 对象占用的内存。
判断内存泄漏看heapUsed字段为准
WeakMap 可以解决内存泄露问题 键必须是对象,因为键是弱引用,在键对象消失后自动释放内存。
因为WeakMap的特殊的垃圾回收机制,所以没有clear()方法。 与Map的不同之处
当使用Dom对象绑定事件时,Dom对象消失后若没有及时释放内存(置null),便会一直存在内存中。 使用WeakMap保存Dom对象不会出现这样的问题,因为Dom对象消失后,JS的垃圾回收机制便会自动释放其所占用的内存
<button type="button" id="btn">按钮</button> <script> let wm = new WeakMap(); let btn = document.querySelector('#btn'); wm.set(btn, {count: 0}); btn.addEventListener('click', () => { let v = wm.get(btn); v.count++; console.log(wm.get(btn).count); }); // 1 2 3 4 5... </script>
总结一些前端常见的面试笔试题,来和大家分享鸭