GC四大算法
一、引用计数法(了解即可)
每个对象有一个引用计数器,当对象被引用一次则计数器加1,当对象引用失效一次,则计数器减1,对
于计数器为0的对象意味着是垃圾对象,可以被GC回收。
目前虚拟机基本都是采用可达性算法,从GC Roots 作为起点开始搜索,那么整个连通图中的对象边都是
活对象,对于GC Roots 无法到达的对象变成了垃圾回收对象,随时可被GC回收。
二、复制算法(Copying)
年轻代中使用的是Minor GC,采用的就是复制算法(Copying)
HotSpot JVM 把年轻代分为了三部分:一个 Eden 区 和 2 个Survivor区(from区 和 to区)。默认比例
为 8:1:1,一般情况下,新创建的对象都会被分配到Eden区(一些大对象特殊处理),这些对象经过第
一次Minor GC后,如果仍然存活,将会被移到Survivor区,对象在Survivor中每熬过一次Minor GC ,
年龄就会增加1岁,当它的年龄增加到一定程度时,就会被移动到年老代中,因为年轻代中的对象基本上
都是朝生夕死,所以在年轻代的垃圾回收算法使用的是复制算法!复制算法的思想就是将内存分为两
块,每次只用其中一块,当这一块内存用完,就将还活着的对象复制到另外一块上面。复制算法不会产
生内存碎片!
如何判断哪个是to区呢?一句话:谁空谁是to
优点:没有内存碎片
缺点 :
1、浪费了一半的内存
2、如果对象的存活率很高,我们可以极端一点,假设是100%存活,那么我们需要将所有对象都复制一
遍,并将所有引用地址重置一遍。复制这一工作所花费的时间,在对象存活率达到一定程度时,将会变
的不可忽视,所以从以上描述不难看出。复制算法要想使用,最起码对象的存活率要非常低才行,而且
最重要的是,我们必须要克服50%的内存浪费。
三、标记清除(Mark-Sweep)
说明:老年代一般是由标记清除或者是标记清除与标记整理的混合实现
什么是标记清除 ?
回收时,对需要存活的对象进行标记
缺点:这个算法效率比较低(递归与全堆对象遍历),需要暂停整个应用,还会产生内存碎片。
四、标记压缩(Mark-Compact)
标记整理说明:老年代一般是由标记清除或者是标记清除与标记整理的混合实现
缺点 : 效率更加的低
优点:标记、整理算法不仅可以弥补 标记、清除算法当中,内存区域分散的缺点,也消除了复制算法当中,内
存减半的高额代价
标记清除压缩(Mark-Sweep-Compact)
几种GC算法的性能分析
内存效率:复制算法 > 标记清除算法 > 标记整理算法 (时间复杂度)
内存整齐度:复制算法 = 标记整理算法 > 标记清除算法
内存利用率:标记整理算法 = 标记清除算法 > 复制算法
所以没有最好的算法,只有最合适的算法 (分代收集算法)
分代收集算法
年轻代对象存活率低 ,所以采用复制算法
老年代对象存活率高,一般是由标记清除或者是标记清除与标记整理的混合实现
GC算法和垃圾收集器的关系
GC算法(引用技数 / 复制 / 标记清除 / 标记整理)是内存回收的方法论,垃圾收集器是算法的落地实现;
目前为止还没有完美的收集器出现,更没有万能的收集器,只有针对具体应用最合适的收集器,进行分代收集
4种垃圾收集器
一、串行垃圾回收器(Serial 和Serial Old)
它为单线程环境设计,且只使用一个线程进行垃圾回收,会暂停所有的用户线程,所以不适合服务器环境
二、并行垃圾回收器 (Parallel)
多个垃圾收集线程并行工作,此时用户线程是暂停的,适用于科学计算/大数据处理首台处理等弱交互场景
三、并发垃圾回收器 (CMS)
用户线程和垃圾收集线程同时执行(不一定并行,可能交替执行)不需要停顿用户线程。互联网公司多用,适用对响应时间有要求的场景
四、G1垃圾收集器
特点:
1、G1能充分利用多CPU、多核环境硬件优势,尽量缩短 STW。
2、G1整体上采用标记-整理算法,局部是通过复制算法,不会产生内存碎片。
3、宏观上G1之中不再区分年轻代和老年代,把内存划分成多个独立的子区域(Region),可以近似理
解为一个围棋的棋盘。
4、G1收集器在物理层面上是不分年轻代和老年代,但是在逻辑上还是会去区分,所以依旧是用分代收集算法
5、G1虽然也是分代收集器,但整个内存分区不存在物理上的年轻代与老年代的区别,也不需要完全独
立的 survivor(to space)堆做复制准备。G1只有逻辑上的分代概念,或者说每个分区都可能随G1的运
行在不同代之间前后切换。