主要有五种GC:
1.Serial GC
Serial体现在工作是单线程的,精简,但是垃圾收集时会进入"stop-the-world"状态。是JDK8中client模式下默认GC。新生代的Serial GC采用复制算法,老年代的Serial GC采用标记-整理算法,由于区别算法不同,老年代的Serial GC专称Serial Old。
-XX:+UseSerialGC
2.ParNew GC
Serial GC的多线程版本,一般用于新生代,配合老年代的CMS GC使用,CMS GC也是并发的。
-XX:+UseConcMarkSweepGC 或者 -XX:+UseParNewGC
3.Parrallel GC
也是Serial GC的多线程版本,是JDK8中server模式下的默认GC,吞吐量优先。
-XX:+UseParallelGC
4.CMS GC
并发GC,减少停顿时间,但是会占用更多CPU资源和用户争抢线程,基于标记-清除算法,可能产生内存碎片化问题,因此长时间后会触发full GC,而full GC停顿时间是很长的。
5.G1 GC
兼顾吞吐量和停顿时间,JDK9以后的默认GC。G1仍然有年代概念,但是维护成了一个个region,即新生代的edon、from以及to区域,包括老年代都是一个个region。通过remembered set维护region之间的关系,虽然开销比较大,但是好处也多。region之间采用的是复制算法,但其实可以看成标记-整理算法,可以避免内存碎片化。G1还有一个Humongous的概念,Humongous也是一个region,属于老年代,超大对象直接放入老年代就是直接放进Humongous中,有时候Humongous占用了不止一个region。
主要有三种算法:
1.复制算法
需要预留一部分内存空间,造成浪费,但是可以避免内存碎片化。如果是数组这类对象需要连续内存空间的,没有地方放就会触发full GC,甚至OOM。
2.标记-清除
可能造成内存碎片化
3.标记-整理
标记-整理也会去清除,不会在清除的过程中会将未被清除的对象移动位置,这样可以避免内存碎片化。