1.为什么要分代

V8是Chrome浏览器的javascript解释器,为什么需要把堆分代?不分代不能完成他所做的事情么?其实不分代完全可以,分代的唯一理由就是优化GC性能。你先想想,如果没有分代,那我们所有的对象都在一块,GC的时候我们要找到哪些对象没用,这样就会对堆的所有区域进行扫描。而我们的很多对象都是朝生夕死的,如果分代的话,我们把新创建的对象放到某一地方,当GC的时候先把这块存“朝生夕死”对象的区域进行回收,这样就会腾出很大的空间出来。

2.怎么分代

首先堆内存分为新生代和老生代。新生代又分为了三部分:1个Eden区和2个Survivor区(分别叫from和to)。默认比例为8:1:1。

2.为什么要设置Survivor区

Survivor的存在意义,就是减少被送到老年代的对象,进而减少Full GC的发生,Survivor的预筛选保证,只有经历16次Minor GC还能在新生代中存活的对象,才会被送到老年代。

3.为什么要设置两个Survivor区

  • Minor GC 会清理年轻代的内存。
  • Major GC 是清理老年代。
  • Full GC 是清理整个堆空间—包括年轻代和老年代。

为什么一个Survivor区不行?第一部分中,我们知道了必须设置Survivor区。假设现在只有一个survivor区,我们来模拟一下流程: 
刚刚新建的对象在Eden中,一旦Eden满了,触发一次Minor GC,Eden中的存活对象就会被移动到Survivor区。这样继续循环下去,下一次Eden满了的时候,问题来了,此时进行Minor GC,Eden和Survivor各有一些存活对象,如果此时把Eden区的存活对象硬放到Survivor区,很明显这两部分对象所占有的内存是不连续的,也就导致了内存碎片化

那么,顺理成章的,应该建立两块Survivor区,刚刚新建的对象在Eden中,经历一次Minor GC,Eden中的存活对象就会被移动到第一块survivor space S0,Eden被清空;等Eden区再满了,就再触发一次Minor GC,Eden和S0中的存活对象又会被复制送入第二块survivor space S1(这个过程非常重要,因为这种复制算法保证了S1中来自S0和Eden两部分的存活对象占用连续的内存空间,避免了碎片化的发生)。S0和Eden被清空,然后下一轮S0与S1交换角色,如此循环往复。如果对象的复制次数达到16次,该对象就会被送到老年代中。

 
上述机制最大的好处就是,整个过程中,永远有一个survivor space是空的,另一个非空的survivor space无碎片

那么,Survivor为什么不分更多块呢?比方说分成三个、四个、五个?显然,如果Survivor区再细分下去,每一块的空间就会比较小,很容易导致Survivor区满,因此,我认为两块Survivor区是经过权衡之后的最佳方案。

4.怎么GC

一般情况下,新创建的对象都会被分配到Eden区(一些大对象特殊处理),这些对象经过第一次Minor GC后,如果仍然存活,将会被移到Survivor区。

对象在Survivor区中每熬过一次Minor GC,年龄就会增加1岁,当它的年龄增加到一定程度时,就会被移动到年老代中。

因为年轻代中的对象基本都是朝生夕死的(80%以上),所以在年轻代的垃圾回收算法使用的是复制算法,复制算法的基本思想就是将内存分为两块,每次只用其中一块,当这一块内存用完,就将还活着的对象复制到另外一块上面。复制算法不会产生内存碎片。

在GC开始的时候,对象只会存在于Eden区和名为“From”的Survivor区,Survivor区“To”是空的。紧接着进行GC,Eden区中所有存活的对象都会被复制到“To”,而在“From”区中,仍存活的对象会根据他们的年龄值来决定去向。年龄达到一定值(年龄阈值,可以通过-XX:MaxTenuringThreshold来设置)的对象会被移动到年老代中,没有达到阈值的对象会被复制到“To”区域。经过这次GC后,Eden区和From区已经被清空。这个时候,“From”和“To”会交换他们的角色,也就是新的“To”就是上次GC前的“From”,新的“From”就是上次GC前的“To”。不管怎样,都会保证名为To的Survivor区域是空的。Minor GC会一直重复这样的过程,直到“To”区被填满,“To”区被填满之后,会将所有对象移动到年老代中。

为了确保js的正常执行,gc和js执行不能并行执行,因此选择了类似于共享CPU时间片的执行方式,将gc 和js交替执行。

最新文章

  1. angular学习笔记(二十八-附1)-$resource中的资源的方法
  2. Caffe学习
  3. 消息队列之ZeroMQ(C++)
  4. iOS Swift 数组 交换元素的两种方法
  5. Dom终
  6. ios7中的多任务
  7. [Z] 关于c++ typename的另一种用法
  8. [CSS]图片与文字对齐问题
  9. Effective Modern C++翻译(4)-条款3:了解decltype
  10. lua string 库
  11. C算法分解质因数与分解因子
  12. Python变量之白首如新,倾盖如故
  13. python中字符串的拼接
  14. linux搭建zabbix server
  15. [转]SPI通信原理简介
  16. hadoop 学习笔记2
  17. 日志插件 log4net 的配置和使用
  18. 用ng-style修改元素的color, size等
  19. apache启动报错(98)Address already in use: make_sock: could not bind to address [::]:80
  20. [Web 前端] 解决因inline-block元素导致的空白间距和元素下沉

热门文章

  1. gc笔记(转)
  2. S-CMS企建v3二次SQL注入
  3. 全面解密QQ红包技术方案:架构、技术实现、移动端优化、创新玩法等
  4. Python面试真题第二节
  5. linux系统安装cdcfordb2udb
  6. CKEditor上传视频(java)
  7. 11.Flask钩子函数
  8. cmd命令窗口的快速选中复制黏贴
  9. 浅谈Web开发中的定时任务
  10. PHP_D4_“简易聊天室 ”的具体技术实现