GC垃圾回收算法和垃圾收集器的关系?
GC算法(引用计数/复制/标清/标整)是内存回收的方法论,垃圾收集器就是算法落地的实现。
四种主要垃圾收集器:
垃圾回收的方式:Serial、Parallel、CMS、G1
串行垃圾回收器(Serial):它为单线程环境设计且只使用一个线程进行垃圾回收,会暂停所有的用户线程。所以不适合服务器环境;
并行垃圾回收器(Parallel):多个垃圾收集线程并行工作,此时用户线程是暂停的,适用于科学计算/大数据处理首台处理等弱交互场景;
并发垃圾回收器(CMS):用户线程和垃圾收集线程同时执行(不一定是并行,可能交替执行),不需要停顿用户线程互联网公司多用它,适用对响应时间有要求的场景;
G1垃圾回收器:G1垃圾回收器将堆内存分割成不同的区域然后并发的对其进行垃圾回收;
如何查看默认的垃圾收集器?
默认垃圾收集器有哪些?
ava的gc回收的类型主要有几种 ::
UseSerialGc,UseParallelGC, UseConcMarkSweepGC, UseParNewGC,** UseParallelOldGC**, UseG1GC
垃圾收集器
垃圾收集器约定参数说明
Server/Client模式所代表的含义
新生代
串行GC(Serial)/(Serial Copying)
串行收集器是最古老,最稳定以及效率高的收集器,只使用一个线程去回收但其在进行垃圾收集过程中可能会产生较长的停顿(“Stop-The-world”状态)。虽然在收集垃圾过程中需要暂停所有其他的工作线程,但是它简单高效,对于限定单个CPU环境来说,没有线程交互的开销可以获得最高的单线程垃圾收集效率,因此Serial垃圾收集器依然是java虚拟机运行在CIient模式下默认的新生代垃圾收集器。
并行GC(ParNew)
并行回收GC(Parallel)/(Parallel Scavenge)
老年代
串行GC(Serial Old)/(SerialMSC)
Serial Old 是 Serial 垃圾收集器老年代版本,它同样是个单线程的收集器,使用标记-整理算法,这个收集器也主要是运行在 Client默认的java虚拟机默认的年老代垃圾收集器。
在Server模式下,主要有两个用途(了解,版本已经到8及以后):
1.在JDK1.5之前版本中与新生代的Parallel Scavenge 收集器搭配使用。( Parallel Scavenge + Serial Old )
2.作为老年代版中使用CMS收集器的后备垃圾收集方案。
并行GC(Parallel old)/(Parallel MSC)
-Xms10m -Xmx10m -XX:+PrintGCDetails -XX:+PrintCommandlineFlags -XX:+UseParalleloldGC
并发标记清除GC(CMS)
四大步骤
- 初始标记:只是标记一下GC Roots能直接关联的对象,速度很快,仍然需要暂停所有的工作线程。
- 并发标记(CMS concurrent mark)和用户线程一起:进行GC Roots跟踪的过程,和用户线程一起工作,不需要暂停工作线程。 主要标记过程,标记全部对象
- 重新标记(CMS remark):为了修正在并发标记期间,因用户程序继续运行而导致标记产生变动的那一部分对象的标记记录,仍然需要暂停所有的工作线程。
由于并发标记时,用户线程依然运行,因此在正式清理前,再做修正 - 并发清除(CMS concurrent sweep)和用户线程一起:清除GC Roots不可达对象,和用户线程一起工作,不需要暂停工作线程。基于标记结果,直接清理对象;
由于耗时最长的并发标记和并发清除过程中,垃圾收集线程可以和用户现在一起并发工作,所以总体上来看CMS 收集器的内存回收和用户线程是一起并发地执行。
优缺点
优点:并发收集低停顿
缺点:1、并发执行,对CPU资源压力大
由于并发进行,CMS在收集与应用线程会同时会增加对堆内存的占用,也就是说,CMS必须要在老年代堆内存用尽之前完成垃圾回收,否则CMS回收失败时,将触发担保机制,串行老年代收集器将会以STW的方式进行一次GC,从而造成较大停顿时间
2、采用的标记清除算法会导致大量碎片
标记清除算法无法整理空间碎片,老年代空间会随着应用时长被逐步耗尽,最后将不得不通过担保机制对堆内存进行压缩。CMS也提供了参数-XX:CMSFulIGCsBeForeCompaction(默认0,即每次都进行内存整理)来指定多少次CMS收集后,进行一次压缩的Full GC。
如何选择垃圾收集器?
G1垃圾收集器
G1 (Garbage-First) 收集器,是一款面向服务端应用的收集器;
底层原理
Region区域化垃圾收集器
最大好处是化整为零,避免全内存扫描,只需要按照区域来进行扫描即可。