Garbage Collection

gc.svg

GC垃圾回收线程,与之对应的是用户线程. 收集垃圾时STWStop The World,进行检索垃圾,会导致用户线程暂停,影响应用。JVM在进行GC时,并非每次都对三个内存Young、Old、method area区域一起回收,大部分时候回收指Young区

针对Hotspot JVM实现,GC按照回收区域分为两大类型

  • 部分收集partial GC:不是完整收集整个heap area的垃圾收集
    • 新生代收集 Minor GC/Young GC: 只是Young区Eden区、s0或s1的垃圾收集
    • 老年代收集 Major GC/Old GC: 只是Old区的垃圾收集
      • 目前只有 Concurrent并发Mark SweepCMS Collector会有单独收集老年代的行为
      • 注意,很多时候Major GC会和Full GC混淆使用,需要具体分辨是Old区回收还是整堆回收
    • 混合收集 Mixed GC:收集整个新生代以及部分老年代的垃圾收集
      • 目前只有Garbage-FirstG1 Garbage Collector.会有这种行为
  • 整堆收集Full GC: 收集整个heap areamethod area的垃圾收集

调优就是减少GC出现次数. 主要调优Major GCFull GC

Minor GC

  • Eden区满触发
  • Survivor区满不会引发MinorGC
  • 每次MinorGC会清理Young区Eden区、s0或s1
  • MinorGC非常频繁
  • 回收速度快
  • 会引发STWStop The World,暂停其他用户线程,等待垃圾回收结束,用户线程才恢复运行

Major GC

  • 对象从Old区消失时,则发生了Major GCFull GC
  • 出现Major GC 经常会伴随至少一次的MinorGC但非绝对,在Parallel Scavenge收集器的收集策略里直接进行MajorGC的策略选择过程
    • Old区不足时,会先尝试触发MinorGC,如果之后空间还不足,则触发MajorGC
  • Major GCMinor GC慢10倍以上STW的时间更长
  • Major GC后内存还不足,会抛出OOM异常

Full GC

  • 触发机制
    • 调用System.gc()时,系统建议执行Full GC,但是不必然执行
    • Old区空间不足
    • method area空间不足
    • 通过Minor GC后晋升Old区的对象平均大小,大于Old区的可用内存
    • Eden区Survivor Form区Survivor To区复制时,对象大小大于Survivor To区可用内存,则把该对象转存到Old区,且Old区的可用内存小于该对象大小
  • 说明:Full GC是开发或调优中尽量要避免的,这样STW时间会短一些