chrome v8引擎以及垃圾回收机制(原创)

以前在携程的时候专门做了一次关于v8引擎垃圾回收相关的调研和分享,这方面文章非常少,在这里写出来,也算是记录一下。

啥是垃圾回收?

垃圾回意思是,GC会尝试去重新分配已经不需要的对象所占据的内存空间。如果你的程序中仍然存在指向一个对象的引用,那么该对象将不会被回收。

特点是:ECMAScript没有暴露任何垃圾回收器的接口,我们无法强迫其进行垃圾回收,更无法干预内存管理。

所以我们没有办法使用JS去主动操作GC,在大多数的情况下,我们也没有必要去手动得解除对象的引用。只要简单地把变量放在它们应该的地方(局部变量的方式),垃圾就能正确地被回收。


V8内存分配及限制

chrome V8 中,所有的 JavaScript 对象都是通过堆内存來进行內存分配的。(大家可以看下堆、栈的区别)

原理:当声明变量并赋值时,V8 就会在堆內存中分配一部分给这个变量。如果已申请的內存不足以存储这个变量,V8 就会继续申请,直到堆的大小达到了 V8 的內存上限为止。

特意查了一下,默认情況下,V8 的堆內存的大小上限在64位系統中为 1.4G,在32位系統中則為0.7G左右。

这个不是非常准确,也没有官方发布。我查了一下google 技术博客,


堆内存分配的几种形式
  • 静态分配:全局变量,函数之类的分配方式,由于他们页面没有关闭之前,他们是不会被清除的。(代码编译时)
  • 动态分配:使用new创建出来的,主动要求给分配空间的。(代码执行时)


经验法则

为了使垃圾回收器尽早回收尽可能多的对象,不要保留不再需要的对象。这里有几点需要谨记:
  • 在恰当的作用域中使用变量。尽量在函数作用域中声明变量,而尽可能不要声明不会被回收的全局变量,这将意味着更干净更省心的代码。
  • 确保解绑那些不再需要的事件监听器。尤其是那些即将被移除的 DOM 对象所绑定的事件。
  • 避免缓存中储存大量不会被重用的数据。
  • 少用闭包


最后写一下JS中会常驻内存的一些写法:

1、全局变量

尽量避免全局变量。全局变量 常驻内存,GC不能回收。
全局对象只会在刷新页面、导航到其他页面、关闭标签页或退出浏览器时才会被清理。函数作用域的变量将在超出作用域时被清理,即退出函数时,已经没有任何引用,这样的变量就被清理了。

2、JS对象引用

function ob(){
    var bar  = new largeObject(); //很大一个对象\变量\字符串
    bar.someCall();
    return bar;
}

var a = new ob();

现在有一个指向 bar 对象的引用,当 ob 调用结束后,bar 对象不会被回收,
直到变量a分配其他引用(或者 a 超出了作用域范围)。复制代码

3、DOM 事件(目前使用vue,react框架等已经很少直接操作dom了,可以忽略了)

var c= document.getElementById('content');
c.innerHTML = '<button id="button">click</button>';

var b= document.getElementById('button');
b.addEventListener('click', function(){});

content.innerHTML = '';
虽然 <button> 从 DOM 中移除了,由于它的监听器还在,所以无法被 GC 回收。
要避免这种情况就是通过 removeEventListener 将回调函数去掉。复制代码

4、定时器,定时器不用的时候记得要clearTimeout

应该还有其他一些,就不举例子了


Chrome DevTools中提供了很多内存分析工具,内存快照等,关注devtools中的performance、memory、take heap snapshot等



  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值