java基础之垃圾收集器

概述

上一篇主要说了GC的过程,这里总结一下java的几种收集器和算法

前置结论

  • 尽可能将对象分配到新生代,因为full GC成本高于minor GC
  • 尽量少使用大对象
  • JIT编译参数
  • 发生oom时执行脚本 -XX:OnoomError=D:\reset.bat
  • 获取GC日志 -Xloggc:D:\gclog.txt
  • tomcat catalina.bat参数调优

算法

标记-清除

java基础之垃圾收集器

首先标记出所有需要回收的对象,标记完成以后统一进行回收。
标记过程参照上一篇不可达对象部分,其缺点有2个

  1. 效率问题,标记、清除过程效率都不高
  2. 空间碎片问题,当有较大对象的时候,不得不触发一次GC
复制算法

java基础之垃圾收集器

  • 虽然这种算法实现简单,运行高效,但是代价太高。只能使用一半的空间。但是这种算法也带来一种思路,新生代中的对象 消失的很快,不需要按照1:1来分配,HotSpot默认Eden和Survivor1、Survivor2是8:1:1,当回收时,将Eden和Survivor(其中一个)一起复制到另外一块没有使用的Survivor中, 也就等于新生代有90%可以利用。
  • 如果另一块Survivor没有足够的内存来接收上一次存活的对象,这些对象通过分配担保机制直接进入老年代。
  • 复制算法比较适用于新生代。因为复制算法在存活对象比较多的时候,效率会降低,所以老年代不适用。
标记-整理算法

java基础之垃圾收集器

  • 针对老年代的特点,与标记-清除算法的标记过程一样,但是之后是让所有存活的对象向另一端移动,然后直接清理掉边界以外的对象
  • 既避免了内存碎片,也不需要两块相同的空间,性价比较高
分代收集算法

当前商业虚拟机都采用该算法,根据对象存活时期的不同,将内存分为几块,一般是分为新生代和老年代,在根据不同年代的不同特性来选择最适合的收集算法

  • 新生代 复制算法
  • 老年代 标记-整理算法
    综上所述,收集器可以做以下分类
  • 按照线程来分,串行收集器和并行收集器
  • 按工作模式来分,并发式和独占式
  • 按碎片处理方式,压缩式和非压缩式
  • 按工作内存,新生代和老年代