GC垃圾回收
一、堆内存分区
YGC Minor GC
Eden区不足
FGC
Full GC
Old区不足
多数情况下对老年代回收的时候对年轻代也会回收
二、GC方法
第一种:标记清除
原理:分为标记和清除两个阶段:首先标记出所有的需要回收的对象,在标记完成以后统一回收所有被标记的对象。
特点:(1)效率问题,标记和清除的效率都不高;(2)空间的问题,标记清除以后会产生大量不连续的空间碎片,空间碎片太多可能会导致程序运行过程需要分配较大的对象时候,无法找到足够连续内存而不得不提前触发一次垃圾收集。
使用地方 :适合在老年代进行垃圾回收,比如CMS收集器就是采用该算法进行回收的。
第二种:标记整理
原理:分为标记和整理两个阶段:首先标记出所有需要回收的对象,让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存。
特点:不会产生空间碎片,但是整理会花一定的时间。
使用地方:适合老年代进行垃圾收集,parallel Old(针对parallel scanvange gc的) gc和Serial old收集器就是采用该算法进行回收的。
第三种:复制算法
原理:它先将可用的内存按容量划分为大小相同的两块,每次只是用其中的一块。当这块内存用完了,就将还存活着的对象复制到另一块上面,然后把已经使用过的内存空间一次清理掉。
特点:没有内存碎片,只要移动堆顶指针,按顺序分配内存即可。代价是将内存缩小位原来的一半(缺点)。
使用地方:适合新生代区进行垃圾回收。serial new,parallel new和parallel scanvage
收集器,就是采用该算法进行回收的。
复制算法改进思路:由于新生代都是朝生夕死的,所以不需要1:1划分内存空间,可以将内存划分为一块较大的Eden和两块较小的Suvivor空间。每次使用Eden和其中一块Survivor。当回收的时候,将Eden和Survivor中还活着的对象一次性地复制到另一块Survivor空间上,最后清理掉Eden和刚才使用过的Suevivor空间。其中Eden和Suevivor的大小比例是8:1。缺点是需要老年代进行分配担保,如果第二块的Survovor空间不够的时候,需要对老年代进行垃圾回收,然后存储新生代的对象,这些新生代当然会直接进入来老年代。
三、对象生成到GC过程
start ->new
(优先)栈如果能分配的下,那就在栈分配,不用牵扯任何垃圾回收器。
其次
太大了直接去Old区 Old去是fullGC (mark compact 标记整理算法)
不够大 TLAB(Thread Local Allocation Buffer 线程的局部缓存区)分配
GC一次进survival区 (copy算法)
关于年龄代,GC一次没回收掉+1,刚开始的是0
四、Garbage Collectors 垃圾回收器
young 年轻代
1、serial young :a stop-the-world,copying(拷贝算法) collector which uses a single GC thread
注解:stop-the-world即停止整个世界~,就是在垃圾回收的时候线程都要乖乖的停下来等垃圾回收完了再继续,所以很有趣的叫它停下整个世界
2、parallel scavenge:a stop-the-world,copying collector which uses multiple GC threads
注解:不同于单线程的serial的单个GC线程去清理,会有多个GC线程去清理垃圾
old 老年代
1、serial old: a stop-the-world,mark-sweep-compact (标记整理算法) collector which uses a single GC thread
一样也是停止整个世界
2、parallel old
3、CMS:CMS(Concurrent Mark-Sweep)(并发 标记-清除)是以牺牲吞吐量为代价来获得最短回收停顿时间的垃圾回收器。(下图)
CMS算法能够实现垃圾回收器工作的时候,线程可以同时干活