JS 内存泄漏

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
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值