Minor GC,Major GC,Full GC -- hotspot VM GC讲解

来源:互联网 发布:招聘seo主管 编辑:程序博客网 时间:2024/05/16 18:20
针对HotSpot VM的实现,它里面的GC其实准确分类只有两大种:
  • Partial GC:并不收集整个GC堆的模式
    • Young GC:只收集young gen的GC
    • Old GC:只收集old gen的GC。只有CMS的concurrent collection是这个模式
    • Mixed GC:收集整个young gen以及部分old gen的GC。只有G1有这个模式
  • Full GC:收集整个堆,包括young gen、old gen、perm gen(如果存在的话)等所有部分的模式。

Major GC通常是跟full GC是等价的,收集整个GC堆。但因为HotSpot VM发展了这么多年,外界对各种名词的解读已经完全混乱了,当有人说“major GC”的时候一定要问清楚他想要指的是上面的full GC还是old GC。


对于 Hotspot 中常见的收集器 :serial GC,  parallel GC, CMS(concurrent Mark Sweep),G1(garbage first garbage collector)这是收集器算法,就是选择何时触发minor GC,和 full GC.

比如:

serial GC单线程 收集器,它要是执行,那么应用线程都得终止。触发条件:

  • young GC:当young gen中的eden区分配满的时候触发。注意young GC中有部分存活对象会晋升到old gen,所以young GC后old gen的占用量通常会有所升高。
  • full GC:当准备要触发一次young GC时,如果发现统计数据说之前young GC的平均晋升大小比目前old gen剩余的空间大,则不会触发young GC而是转为触发full GC(因为HotSpot VM的GC里,除了CMS的concurrent collection之外,其它能收集old gen的GC都会同时收集整个GC堆,包括young gen,所以不需要事先触发一次单独的young GC);或者,如果有perm gen的话,要在perm gen分配空间但已经没有足够空间时,也要触发一次full GC;或者System.gc()、heap dump带GC,默认也是触发full GC。

  • Parallel Scavenge(-XX:+UseParallelGC)框架下,默认是在要触发full GC前先执行一次young GC,并且两次GC之间能让应用程序稍微运行一小下,以期降低full GC的暂停时间(因为young GC会尽量清理了young gen的死对象,减少了full GC的工作量)。
    Parallel GC 执行也是终止所有的应用线程,但是这个收集器是多线程的,目的就是利用CPU的多核资源。

    ---目前客户端应用程序采用上述两种收集器。服务器端一般采用CMS 和 G1垃圾收集器,Java9 将默认采用G1垃圾收集器。


    这张图来自于《深入理解Java虚拟机--jvm最高特性与最佳实践    周志明》,这张图也是很多Java初学者了解Hotspot GC需要记住了解的图。
    下面 就说明一下图中这些minor GC,先说serialNew 和 serialOld 这个是单线程的,也就是stop all of world,当然其他的GC,比如parallelOld 和 parNew虽是多线程收集,但是还是stop the world.serialold 或者 serialNew 单线程,回收效率较低,那么为什么现在还在使用???那是因为其算法简单,停止所有应用线程去专心收集垃圾,收集效率极高,几乎把你所有没有使用到的对象垃圾都给你收回来。专心做收集,那么你的内存空间能多大呢?还不得几十毫秒或者几百毫秒就给你搞定的事情。停顿也是极短的时间。所以这个垃圾回收器一直都在使用。在client程序中也是主导的。

    parNew 和 parallel Old 垃圾回收器和serial很相近,无非就是使用了多线程,目的就是借助处理器的多核能力。(毕竟现在处理器都是多核的)

    parallel Scavenge 这个较为特殊的GC,其目的是为了实现最大的吞吐量,吞吐量=用户任务处理时间 / (用户处理时间 + 垃圾回收时间);说白了我就是给用户开口让其设置参数
    来限制垃圾回收的时间,怎么限制垃圾回收时间,就是让垃圾不是那么彻底的回收干净,牺牲一定的yong 代空间,那么我让你回收时间缩短,增加吞吐量。

    CMS consurrent mark sweep 这个回收器是在old 代的,主要和其他yong代配合使用,上述图中,只要垃圾回收器之间有连接线,那么就可以配合使用。CMS看其名称就知道基于标记-清除算法,标记清除-清除算法,有好处,啥好处?就是省空间,不复制,不节省空间嘛。但是产生垃圾碎片,导致存储空间不连续。有没有好的垃圾清除算法(垃圾清除算法主要就是标记算法,复制算法,标记-清除算法,标记整理算法),好的算法就是标记-整理算法,但是复杂呀!!!CMS是要降低停顿时间,你搞个那么复杂的算法,回收时间咋控制。
    CMS工作主要分为四个步骤,初始标记--并发标记--重复标记--并发清除;初始标记和重复标记是stop the word,为啥??? 标记的时候为了标记的准确同时对整个old空间都做标记,应用线程不得停顿嘛!并发标记的时候是基于初始标记的结果,所以用户线程可以运行,所以这个过程是并发的。重复标记是同一个道理,回收的时候,就是多线程并发回收。CMS在回收的时候由于分多个过程,回收时间也稍稍长,那么这个过程中,用户线程并发性能回收影响。

    在CMS收集垃圾的时候,会给用户线程留点空间,用于用户存储old数据,如果在垃圾回收的过程中,这块小区域满了,那么用户线程都要被停止。

    G1垃圾回收器,garbage first,就是讲堆区划分很多的区域块,优先回收优先级较高的区域,而且会综合之前回收的经验,统计便于收集或者这块区域较为重要,或者垃圾较多的区域,对其优先收集。而且在手机过程中,其他区域是可以提供给用户开销的,所以G1几乎使得用户线程不停顿。




    原创粉丝点击