收集器

 

不同的垃圾收集器代表不同的回收算法  
Serial收集器是针对新生代的收集器,采用的是Copying算法 Serial Old收集器是针对老年代的收集器,采用的是Mark-Compact算法,标记-压缩算法
Parallel 并行收集器 Copying算法
Parallel Old收集器 并行收集器 Mark-Compact算法
CMS收集器是基于“”标记--清除”(Mark-Sweep)算法实现的

回收算法

可达性分析算法 http://www.imooc.com/article/36845      gc优化 https://blog.csdn.net/myle69/article/details/80957776
算法思路:通过一系列称为GC Roots的对象作为起始点,从这些节点开始向下搜索,搜索所走过的路径称为引用链(Reference Chain),当一个对象到GC Roots没有任何的引用链,(也就是从GC Roots到这个对象不可达),那么证明此对象是不可用的。

标记-清除算法
标记:首先标记所有需要回收的对象,在标记完成之后统计回收所有被标记的对象,它的标记过程即为上面的可达性分析算法
清除:清除所有被标记的对象

复制算法

标记-压缩算法(标记-清除改进)
在老年代的对象大都是存活对象,复制算法在对象存活率教高的时候,效率就会变得比较低。根据老年代的特点,有人提出了“标记-压缩算法(Mark-Compact)”
标记过程与标记-清除的标记一样,但后续不是对可回收对象进行清理,而是让所有的对象都向一端移动,然后直接清理掉端边界以外的内存。
这种方法既避免了碎片的产生,又不需要两块相同的内存空间,因此,其性价比比较高。

分代收集算法(对收集器进行细化配置,比如同时设置 Parallel 和 Parallel Old)
根据对象存活的周期不同将内存划分为几块,一般是把Java堆分为老年代和新生代,这样根据各个年代的特点采用适当的收集算法。
新生代每次收集都有大量对象死去,只有少量存活,那就选用复制算法,复制的对象数较少就可完成收集。
老年代对象存活率高,使用标记-压缩算法,以提高垃圾回收效率。

 

串行、并行收集器

次要收集年轻代 主要收集年老代

1,串行收集器
是最简单的收集器,对于单处理器系统真是绝佳上选。当然,它也是所有收集器里面最不常用的。串行收集器使用一个单独的线程进行收集,不管是次要收集还是主要收集

2,并行收集器(吞吐量优先)
使用最高效算法、多个并行线程进行收集
并行收集器有两种形式:一种并行收集器(-XX:+ UseParallelGC)在次要回收中使用多线程来执行,在主要回收中使用单线程执行;另一种是从Java 7u4开始默认使用的并行旧生代收集器(Parallel Old collector )(XX:+UseParallelOldGC),在次要回收和主要回收均使用多线程。在tenured space分配的对象使用简单的凹凸指针(bump-the-pointer)算法即可。当年老区填满后会触发主要回收。

3,并发收集器(响应时间优先)
CMS(并发标记清理收集器,Concurrent Mark Sweep)
CMS(-XX:+ UseConcMarkSweepGC)收集器在年老代中使用,专门收集那些在主要回收中不可能到达的年老对象。它与应用程序并发运行,在年老代中保持一直有足够的空间以保证不会发生年轻代晋升失败。

晋升失败将会触发一次FullGC,CMS会按照下面几个步骤处理:
初始化标记:寻找GC根。
并发标记:标记所有从GC根开始可到达的对象。
并发预清理:检查被更新过的对象引用和在并发标记阶段晋升的对象。
重标记:捕捉预清洁阶段开始更新的对象引用。
并发清理:通过回收被死对象占用的内存更新可用空间列表。
并发重置:重置数据结构为下一次运行做准备。

当年老对象变得不可访问时,占用空间会被CMS回收并且放入到空闲空间列表中。当晋升发生的时候,会查询空闲空间列表,为晋升对象找到大小合适的位置。这增加了晋升的成本,因而相比并行收集器也增加了次要收集的成本。
注意:CMS 不像压缩收集器,随着时间的推移会在年老代中产生碎片。对象晋升可能失败,因为一个大对象可能在年老代在找不到一块足够容身的可用空间。如果发生了这样的事,日志会记录一条“晋升失败”的消息,然后并且触发一次FullGC来压缩存活的年老对象。对于这种压缩驱动的FullGC,由于CMS使用单线程压缩,可以想见会比使用并行旧生代收集器的主要回收使用更长的暂停时间。
https://blog.csdn.net/u012388497/article/details/17953741

 

年轻代gc-Minor GC
在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”区被填满之后,会将所有对象移动到年老代中。
https://www.cnblogs.com/haitaofeiyang/p/8392268.html

 


并行垃圾回收器相对于串行,是通过多线程运行垃圾收集的。也会stop-the-world。适合Server模式以及多CPU环境。一般会和jdk1.5之后出现的CMS搭配使用,Parallel Scavenge: 关注吞吐量,吞吐量优先,吞吐量=代码运行时间/(代码运行时间+垃圾收集时间),也就是高效率利用cpu时间,尽快完成程序的运算任务
可以设置最大停顿时间MaxGCPauseMillis以及,吞吐量大小GCTimeRatio。如果设置了-XX:+UseAdaptiveSizePolicy参数,则随着GC,会动态调整新生代的大小,Eden,Survivor比例等,以提供最合适的停顿时间或者最大的吞吐量。用于新生代收集,复制算法。通过-XX:+UseParallelGC参数,Server模式下默认提供了其和SerialOld进行搭配的分代收集方式。

并发标记扫描垃圾回收器(CMS)
CMS(Concurrent Mark Sweep)基于“标记—清除”算法,用于老年代,所以其关注点在于减少“pause time”也即因垃圾回收导致的stop the world时间
-XX:+UseParNewGC 设置年轻代为并发收集
CMS最主要解决了pause time,但是会占用CPU资源,牺牲吞吐量。CMS默认启动的回收线程数是(CPU数量+3)/ 4,当CPU<4个时,会影响用户线程的执行。另外一个缺点就是内存碎片的问题了,碎片会给大对象的内存分配造成麻烦,如果老年代的可用的连续空间也无法分配时,会触发full gc

G1(Garbage-First)是在JDK 7u4版本之后发布的垃圾收集器,并在jdk9中成为默认垃圾收集器。通过“-XX:+UseG1GC”启动参数即可指定使用G1 GC。从整体来说,G1也是利用多CPU来缩短stop the world时间,并且是高效的并发垃圾收集器。但是G1不再像上文所述的垃圾收集器,需要分代配合不同的垃圾收集器,因为G1中的垃圾收集区域是“分区”(Region)的。G1的分代收集和以上垃圾收集器不同的就是除了有年轻代的ygc,全堆扫描的fullgc外,还有包含所有年轻代以及部分老年代Region的MixedGC。G1的优势还有可以通过调整参数,指定垃圾收集的最大允许pause time。下面会详细阐述下G1分区以及分代的概念,以及G1 GC的几种收集过程的分类。

Eden regions(年轻代-Eden区)
Survivor regions(年轻代-Survivor区)
Old regions(老年代)
Humongous regions(巨型对象区域)
Free resgions(未分配区域,也会叫做可用分区)

1,G1中的巨型对象是指,占用了Region容量的50%以上的一个对象。因为巨型对象的转移会影响GC效率,所以并发标记阶段发现巨型对象不再存活时,会将其直接回收。ygc也会在某些情况下对巨型对象进行回收
2,分区可以有效利用内存空间,因为收集整体是使用“标记-整理”,Region之间基于“复制”算法,GC后会将存活对象复制到可用分区(未分配的分区),所以不会产生空间碎片。
3,原则上就是G1会计算执行GC的时间,并且极力减少花在GC上的时间(包括ygc,mixgc),如果可能,会通过不断扩展堆空间来满足对象分配、转移的需要
4,G1提供了“可预测的暂停时间”,也是基于G1的启发式算法,所以G1会估算年轻代需要多少分区,以及还有多少分区要被回收。ygc触发的契机就是在Eden分区数量达到上限时。一次ygc会回收所有的Eden和survivor区
https://blog.csdn.net/lijingyao8206/article/details/80513383

 

posted @ 2020-04-19 17:18  XUMT111  阅读(493)  评论(0)    收藏  举报