Hotspot的三种GC算法

JVM内存分代图示

   

Hotspot的三种GC算法_第1张图片

   

   

   

  1. Serial Collector
  • 是JVM在client模式下的默认GC方式,通过JVM参数 -XX:UseSerialGC 来指定。
  • 当Eden空间不足时,触发Minor GC,会先检查之前每次Minor GC晋升到Old区的对象的平均大小,如果Old区的剩余空间小于平均大小,则直接触发Full GC,如果Old区的剩余空间大于平均大小,则看HandlePromotionFailure(-XX:-HandlePromotionFailure)的值。如果为true,仅触发Minor GC,否则再触发一次Full GC。
  • -XX:MaxtenuringThreshold=10(经过10次Minor GC回收,放入Old区)
  • 当Survivor区中的To Space放不下这些对象时,这些对象被放入Old区,如果Old或Perm区空间不足,将会触发Full GC。
  • JVM的GC操作是串行的,JVM中的其他应用程序会全部停止。

       

  1. Parallel Collector

    parallel GC根据Minor GC和Full GC的不同分为三种,分别是ParNewGCParallelGCParallelOldGC

       

  2. ParNewGC
  • 通过-XX:UseParNewGC指定。回收策略与Serial Collector相似,只是回收不是单线程的,而是多线程并行回收
  • Parallel Collector有一个UseAdaptIvePolicy配置参数,用来动态控制Eden,From Space,To Space的TenuringThreshold的大小。

       

  1. ParallelGC
  • Server下默认的GC方式。可以通过-XX:+UseParallelGC参数来强制指定。
  • 并行回收的线程数可以通过-XX:ParallelGCThreads来指定。这个值有个计算公式,如果CPU核心数小于8,线程数可以和核心数一样,如果大于8,值为3+(cpu core*5)/8
  • 可以通过-Xmn来控制young区的大小。
  • young区内的Eden,From Space,To Space的大小通过SuriviorRatio控制,(-XX:SuriviorRadio=8表示Eden与From Space的大小为8:1)。但是默认情况下是通过-XX:initalSuriviorRadio的设置为准,默认为8。
  • 当在Eden中申请内存发生不够的情况时,看当前申请的空间是否大于Eden的一半,如果大于则直接在Old区中分配空间,如果小于则触发Minor GC。
  • 触发Minor GC前会检查过去每次晋升Old区的平均大小是否大于Old区的剩余空间。如果大于则再次触发Full GC,在这次触发后仍会按这个规则重新检查一次,Full GC会执行两次。
  • AlwaysTenure,默认为false,表示Minor GC后存活就晋升到Old区。
  • NeverTenure,默认为false,表示永远晋升到Old区。
  • 如果上面两个值都没有设置的情况下设置UseAdaptIveSizePolicy,启动时以InitialTenuringThresHold值作为存活次数的阈值,在每次GC后会动态调整。
  • 如果不使用UseAdaptIveSizePolicy,则以MaxTenuringThresHold为准。不使用UseAdaptIveSizePolicy则设置参数为-XX:-UseAdaptiveSizePolicy
  • 当Old或Perm区空间不足时,会触发Full GC,如果设置了参数ScavengeBeforeFullGC,在Full GC之前会触发Minor GC。

       

  1. ParallelOldGC
  • 可以使用-XX:+UseParallelOldGC来强制指定。
  • 通过-XX:ParallelGCThreads来指定并行回收的线程数。如果CPU核心数小于8,线程数与核心数一致,大于8则值为3+(cpu core*5)/8
  • 与ParalelGC不同之处在于Full GC。Parallel GC的Full GC清空整个Heap堆中的垃圾对象,清除Perm区中已被卸载的类信息,并进行压缩。而ParallelOldGC清除Heap堆中的部分垃圾对象,并进行部分的空间压缩。
  • GC程序是多线程,当同样暂停其他所有程序。

       

  1. CMS Collector
  • 使用-XX:+UseConcMarkSweepGC来指定。
  • 并发的线程数默认为4(并行GC线程数+3),也可以通过ParallelCMSThreads指定。
  • 既不是Minor GC,也不是Full GC,是基于两种GC之间的一种GC。触发规则是检查Old区或Prem区的使用率。
  • Old区默认达到92%就回收空间,可以通过CMSInitiaingOccupancyFraction参数来指定比例 。这个默认值是通过((100-MinHeapFreeRadio)+(double)( CMSTriggerRadio*MinHeapFreeRadio )/100.0)/100.0计算出来的。其中MinHeapRadio为40,CMSTriggerRadio为80。
  • 如果让Prem也使用CMS GC,可以通过-XX:+CMSClassUnloadingEnabled来设定。默认比例值也是92%。可以通过CMSInitiaingPremOccupancyFraction参数指定比例。这个默认值是通过((100-MinHeapFreeRadio)+(double)(CMSTriggerPermRadio*MinHeapFreeRadio)/100.0)/100.0计算出来的。其中MinHeapFreeRadio为40,CMSTriggerPermRadio为80
  • 触发CMS GC回收的只是Old区或Perm区的垃圾对象。与Minor GC或Full GC没有关系。
  • 这种模式下的Minor GC触发与回收规则与Serial GC基本一致。不同之处只是GC回收变成多线程而已。
  • 有两种情况触发Full GC。一种是Eden分配失败,Minor GC后分配到To Space,To Space不够再分配到Old区,Old区不够则触发Full GC。另外一种情况是,当CMS GC正在进行时先Old区申请内存失败,则会直接触发Full GC。
  • 在HotSpot 1.6中使用这种GC方式时,需要在程序中显示调用System.gc
  • CMS GC触发时机会动态调整,禁止JVM自行触发CMS GC,可以通过配置参数-XX:+UseCMSInitiatingOccupancyOnly来实现。

       

       

       

    Hotspot的三种GC算法_第2张图片

       

       

       

    Hotspot的三种GC算法_第3张图片

       

    Hotspot的三种GC算法_第4张图片

       

       

       

    Hotspot的三种GC算法_第5张图片

       

       

       

       

       

       

   

   

   

   

   

   

   

   

   

   

   

   

   

   

   

   

   

   

   

   

   

   

   

   

   

   

   

   

   

   

你可能感兴趣的:(Hotspot的三种GC算法)