https://auth0.com/blog/four-types-of-leaks-in-your-javascript-code-and-how-to-get-rid-of-them/
https://juejin.im/post/5d0706a6f265da1bc23f77a9
收集的一些内存泄漏的示例:
示例一
IE 8 及以下,一部分对象并不是原生 JavaScript 对象。例如,其 BOM 和 DOM 中的对象就是
使用 C++以 COM(Component Object Model,组件对象模型)对象的形式实现的,而 COM 对象的垃圾 收集机制采用的就是引用计数策略。因此,即使 IE 的 JavaScript 引擎是使用标记清除策略来实现的,但 JavaScript 访问的 COM 对象依然是基于引用计数策略的。换句话说,只要在 IE 中涉及 COM 对象,就会 存在循环引用的问题。
当代码中存在循环引用现象时,“引用计数”算法就会导致问题。下面这个简单的例子,展示了使用 COM 对象导致的循环引用问题:
var element = document.getElementById("some_element");
var myObject = new Object();
myObject.element = element;
element.someObject = myObject;
存在问题:
这个例子在一个 DOM 元素(element)与一个原生 JavaScript 对象(myObject)之间创建了循环 引用。其中,变量 myObject 有一个名为 element 的属性指向 element 对象;而变量 element 也有 一个属性名叫 someObject 回指 myObject。由于存在这个循环引用,即使将例子中的 DOM 从页面中 移除,它也永远不会被回收。
方法:
为了避免类似这样的循环引用问题,最好是在不使用它们的时候手工断开原生 JavaScript 对象与 DOM 元素之间的连接。例如,可以使用下面的代码消除前面例子创建的循环引用:
myObject.element = null;
element.someObject = null;
将变量设置为 null 意味着切断变量与它此前引用的值之间的连接。当垃圾收集器下次运行时,就 会删除这些值并回收它们占用的内存。
注意:
为了解决上述问题,IE9 把 BOM 和 DOM 对象都转换成了真正的 JavaScript 对象。这样,就避免了 两种垃圾收集算法并存导致的问题,也消除了常见的内存泄漏现象。
示例二
node 中查看进程的内存
占用情况:process.memoryUsage() 方法。直接上代码:
var showMem = function(){
var mem = process.memoryUsage()
var format = function (bytes) {
return (bytes / 1024 / 1024).toFixed(2) + 'MB'
}
console.log('Process: heapTotal ' + format(mem.heapTotal) + ' heapUsed '
+ format(mem.heapUsed) + ' rss ' + format(mem.rss))
console.log('--------------------------------------------------------')
}
var useMem = function () {
var size = 20 * 1024 * 1024
var arr = new Array(size)
for (var i=0; i<size; i++) {
arr[i] = 0
}
return arr
}
var total = []
for (var j=0; j<15; j++) {
showMem()
total.push(useMem())
}
showMem()
使用node 执行上述代码,可以查看到内存的变化,直至内存溢出。结果如下:
➜ node memory.js
Process: heapTotal 7.35MB heapUsed 4.20MB rss 20.64MB
--------------------------------------------------------
Process: heapTotal 167.36MB heapUsed 164.24MB rss 182.04MB
--------------------------------------------------------
Process: heapTotal 327.38MB heapUsed 324.24MB rss 342.09MB
--------------------------------------------------------
Process: heapTotal 487.39MB heapUsed 484.25MB rss 502.14MB
--------------------------------------------------------
Process: heapTotal 647.40MB heapUsed 644.25MB rss 662.18MB
--------------------------------------------------------
Process: heapTotal 807.41MB heapUsed 804.25MB rss 744.50MB
--------------------------------------------------------
Process: heapTotal 967.42MB heapUsed 964.25MB rss 849.10MB
--------------------------------------------------------
Process: heapTotal 1127.43MB heapUsed 1124.26MB rss 963.87MB
--------------------------------------------------------
Process: heapTotal 1287.45MB heapUsed 1284.26MB rss 1084.80MB
--------------------------------------------------------
...
FATAL ERROR: CALL_AND_RETRY_LAST Allocation failed - JavaScript heap out of memory
需要注意的是:如果将代码中的 Array 改为 Buffer,结果将会不一样。
原因是 Buffer 对象不同于其他对象,它不经过 V8 的内存分配机制,所以不会受到堆内存的大小限制
。
node 查看系统内存情况
,使用 os 模块的 totalmem(总量) 和 freemem (空闲)方法:
➜ node
> os.totalmem();
8589934592
> os.freemem();
160423936