深入理解Java 虚拟机(周志明)笔记(五)——垃圾收集器(三)

  5.1.3.垃圾回收的具体实现————垃圾收集器.
              有一个垃圾收集器是最好的。不同垃圾收集器适合不同的环境。不同收集器可搭配使用,已达到整体最优。
              概念:
                 1.并发与并行
                    并发(Concurrent):两件事情在同一时刻同时发生,如用户线程与垃圾收集器线程同时执行(使用不同的CPU)
                    并行(Parallel):两件事情在一段时间内同时发生,如多条垃圾收集器线程在一段时间交替执行(使用相同的CPU)
                 2.分代收集:将内存对象分代
                     1.新生代(堆):GC频率最高,采用复制算法,(老年代做内存担保)具体划分为一个Eden区和两个Survivor区
                     2.老年代(堆):GC频率低于新生代,高于永久代,采用标记-整理算法。
                     3.永久代(方法区):GC频率最低,主要清理 废弃常量和无用的类。
                3.GC类型
                  1.新生代GC(Minor GC):指发生在新生代的垃圾收集动作,因为Java对象大多数都具备朝生夕灭的特性,所以Minor GC非常频繁,一般回收速度也比较快。
                  2.老年代GC(Major GC或Full GC):指发生在老年代的垃圾收集动作,出现Major GC,经常会伴随至少一次的Minor GC。Major GC的速度一般会比Minor GC慢10倍以上。


               Hotspot(JDK 1.7)中的垃圾收集器:7个
                1.新生代收集器
                      1.1 Serial 收集器  ————最基本、发展历史最悠久的收集器
                              适用:运行在Client模式下的虚拟机中的新生代
                              特点: 1.单线程GC 
                                    2.在GC时暂停所有用户线程
                              算法:采用复制算法 
                              优点:简单,高效
                              缺点:GC时暂停线程带给用户不良体验
                              搭配:CMS 或Serial Old(MSC)
                      1.2 ParNew收集器 
                              适用:运行在Server模式下的虚拟机中的新生代
                              特点: 1.多线程GC(并行):ParNew是Serial的多线程版本,两者共用了许多代码。
                                    2.在GC时暂停所有用户线程
                              算法:采用复制算法 
                              优点:高效
                              缺点:GC时暂停线程带给用户不良体验,单线程下效果不一定优于Serial
                              搭配:CMS 或Serial Old(MSC) 
                      1.3 Parallel Scavenge收集器
                              适用:新生代收集器,在后台运算而不需要太多交互的任务。
                              特点: 1.多线程GC(并行)
                                    2.在GC时暂停所有用户线程
                                    3.与其他收集器的不同:1.ParNew,CMS等收集器的关注点在于尽可能缩短垃圾收集时用户线程的停顿时间;
                                                           而Parallel Scavenge收集器的目标则是达到一个可控制的吞吐量。
                                                           吞吐量:运行代码时间/(运行用户代码时间+垃圾收集时间)
                                                         2.Parallel Scavenge可采用GC自适应的调节策略


                                          参数: -XX:MaxGCPauseMillis 最大垃圾收集停顿时间
                                                     实现:降低GC停顿时间:牺牲吞吐量和新生代空间(减小新生代空间,GC频率变大,吞吐量降低)
                                                 -XX:GCTimeRatio  垃圾收集时间与运行用户代码时间的比例=垃圾收集时间/运行用户代码时间
                                                 -XX:+UseAdaptiveSizePolicy 使用自适应的调节策略 即不需要指定新生代的大小,Eden与Surivior的比例,晋升老年代的年龄等细节参数,虚拟机自动根据根据当前系统的状态动态调整这些参数以提供最合适的停顿时间或最大的吞吐量。——————GC自适应的调节策略。


                              算法:采用复制算法 
                              优点:高效
                              搭配:Parallel Old或Serial Old(MSC) 
                2.老年代收集器
                      2.1 Serial Old收集器
                               适用:运行在Client模式下的虚拟机中的老年代
                                     Server模式下 a.与Parallel Scavenge搭配
                                                  b.做CMS的后备预案
                              特点: 1.单线程GC,Serial收集器的老年代版本 
                                    2.在GC时暂停所有用户线程
                              算法:采用标记-整理算法
                              优点:简单,高效
                              缺点:GC时暂停线程带给用户不良体验
                              搭配:Serial Old(MSC)或ParNew
                      2.2.ParOld收集器 
                              适用:运行在Server模式下的虚拟机中的新生代
                              特点: 1.多线程GC(并行):Parallel Scavenge的老年代版本
                                    2.在GC时暂停所有用户线程
                              算法: 采用标记-整理算法
                              优点:高效
                              缺点:GC时暂停线程带给用户不良体验,单线程下效果不一定优于Serial
                              搭配: Parallel Scavenge
                      2.3 CMS(Concurrent Mark Sweep)收集器——————Hotspot上第一个真正意义上的并发收集器。
                              适用:运行在Server模式下的虚拟机中的老年代,适合对响应时间要求高的应用。
                              特点: 1.多线程 并发
                              过程:1.初始标记:暂停用户线程,标记GC Roots能直接关联的对象
                                   2.并发标记:用户线程与标记线程并发,进行GC Roots的Trace
                                   3.重新标记:修正并发标记阶段,因用户线程继续运行而导致标记产生变动的那一部分对象的标记记录。
                                   4.并发清除:用户线程与清除线程并发。
                                   
                              算法: 采用标记-清楚算法
                              优点:高效,由于耗时最长的并发标记和并发清除阶段都与用户线程并行工作,故系统停顿时间极短。
                              缺点: 1.对CPU资源非常敏感. 并发时,应用程序会变慢,当CPU数不足时,尤其明显。
                                              解决:增量式并发收集器(i-CMS):在并发标记、清除时让GC线程与用户线程交替运行,以降低GC线程独占CPU的时间。
                                                       当GC时间将变长——————效果一般,被丢弃使用。


                                    2.无法处理浮动垃圾,可能出现“Concurrent Mode "Failure"失败而导致另一次Full GC的产生。    
                                             浮动垃圾:在并发清除阶段,用户线程仍在运行,此时产生的垃圾无法在该次收集中处理。
                                          同时由于要保证并发,就必须预留内存给用户线程使用,因此CMS无法等到老年代几乎完全填满时再进行收集。
                                            JDK 1。5中CMS默认当老年代被使用68%时被激发。1.6中为92%。
                                            当CMS运行期间预留的内存无法满足程序需要,就会出现一次“Concurrent Mode "Failure"失败,这时虚拟机将启动后备预案:临时使用Serial Old收集器来重新进行老年代垃圾收集,这样停顿时间就会很长。
                                    3.产生空间碎片,影响大对象的分配。  往往存在有很大空间剩余,当无法找到足够大的连续空间来分配当前对象,不得不提前出发一次Full GC。
                                          解决: 1.-XX:+UseCMSCompactFullCollection 开关参数(默认开启)
                                                         用于当CMS要进行Full GC时开启内存碎片的合并整理过程,该过程不能并发,故停顿时间变长。
                                                 2.-XX:CMSFullGCsBeforeCompaction 用于设置执行多少次不压缩的Full GC后跟着来一次带压缩的Full GC。
                                                     默认为0,表示每次进入Full GC时都进行碎片整理。
                                                         
                              搭配:Serial或ParNew
                  3.通用收集器(新生代和老年代均适用)
                        3.1 G1收集器
                              适用:面向服务端应用,适用于新生代和老年代。
                              特点: 1.并行+并发。可充分利用CPU资源
                                    2.分代收集。
                                    3.空间整合。 G1从整体看是”标记-整理“算法,从局部(两个Region之间)看,是”复制“算法。 不会产生空间碎片。
                                    4.可预测的停顿。建立可预测的态度时间模型,能让使用者明确指定在一个长度为M毫秒的时间内,消耗在垃圾收集的时间不得超过N毫秒。
                                             G1将内存划分为Region,跟踪各个Region里面的垃圾堆积的价值大小(回收所获得的空间大小以及回收所需时间的经验值),在后台维护一个又想列表,每次根据允许的收集时间,优先回收价值最大的Region。——————Garbage First名称的由来。
                                          难点:虽然内存分为Region,但垃圾收集不能真的以Region为单位进行,因为Region不可能是孤立的,存在某个对象被多个Region的引用,那在做可达性判断确定对象是否存活时,是否需要扫描整个堆空间呢?
                                               注意:此问题在所有的收集器中都存在(如存在新生代与老年代之间的引用)。
                                           解决:1.使用Remembered Set来避免圈堆扫描。
                                                  过程:G1中每个Region都有一个与之对应的Remembered Set,虚拟机发现程序在对Reference类型的数据进行写操作是,会产生一个Write Barrier暂时中断操作,检查Reference类型引用的对象是否处于不同的Region(在分代的例子中就是检查是否老年代的对象引用了新生代中的对象),如果是,便通过CardTable把相关引用信息记录到被引用对象所属的Region的Remembered Set中。当进行内存回收时,在GC根节点的枚举范围中加入Remembered Set即可保证不对全堆扫描也不会有遗漏。




                                    5.内存布局: G1的堆内存布局与其他收集器不同,G1将整个堆内存空间划分为多个大小相等的Region,虽然仍然有新生代和老年代的概念,
                                            但是新生代和老年代不再是物理隔离的,他们都是一部分Region(不需要连续)的集合。
                              过程(与CMS相似):1.初始标记:暂停用户线程,标记GC Roots能直接关联的对象
                                   2.并发标记:用户线程与标记线程并发,进行GC Roots的Trace
                                   3.最终标记修正并发标记阶段,因用户线程继续运行而导致标记产生变动的那一部分对象的标记记录。
                                   4.筛选回收:
                              算法: 全局标记-整理+局部复制算法
                              优点:高效,停顿时间可控、可预测
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值