JVM之垃圾回收-垃圾收集器

欢迎点击访问我的瞎几把整站点:复制未来
文章目录收集器(收集器的多线程版本-使用多条线程进行GC) 为什么只有能与CMS收集器配合收集器GC自适应的调节策略(GC ) Old收集器Old收集器 设置参数 CMS( Mark Sweep)收集器 (三)产生大量内存碎片CMS& Old G1收集器 问题应用场景设置参数运作过程 G1收集器运行示意图 总结
概述
如果说前面介绍的收集算法(JVM之垃圾回收-垃圾收集算法)是内存回收的抽象策略,那么垃圾收集器就是内存回收的具体实现 。
JVM规范对于垃圾收集器的应该如何实现没有任何规定,因此不同的厂商、不同版本的虚拟机所提供的垃圾收集器差别较大,这里只看虚拟机 。
就像没有最好的算法一样,垃圾收集器也没有最好,只有最合适 。我们能做的就是根据具体的应用场景选择最合适的垃圾收集器 。
收集器
(串行)收集器收集器是最基本、历史最悠久的垃圾收集器了(新生代采用复制算法,老生代采用标志整理算法) 。大家看名字就知道这个收集器是一个单线程收集器了 。
它的 “单线程” 的意义不仅仅意味着它只会使用一条垃圾收集线程去完成垃圾收集工作,更重要的是它在进行垃圾收集工作的时候必须暂停其他所有的工作线程( “Stop The World” :将用户正常工作的线程全部暂停掉),直到它收集结束 。
看图理解:
上图中:
当它进行GC工作的时候,虽然会造成Stop-The-World,正如每种算法都有存在的原因,该串行收集器也有存在的原因:因为简单而高效(与其他收集器的单线程比),对于限定单个CPU的环境来说,没有线程交互的开销,专心做GC,自然可以获得最高的单线程效率 。所以收集器对于运行在模式下的应用是一个很好的选择(到目前为止,它依然是虚拟机运行在模式下的默认新生代收集器)
串行收集器的缺点很明显,虚拟机的开发者当然也是知道这个缺点的,所以一直都在缩减Stop The World的时间 。
在后续的垃圾收集器设计中停顿时间在不断缩短(但是仍然还有停顿,寻找最优秀的垃圾收集器的过程仍然在继续)
整理一下前面关于收集器的知识
特点应用场景对于限定单个CPU的环境来说,收集器没有线程交互(切换)开销,可以获得最高的单线程收集效率;在用户的桌面应用场景中,可用内存一般不大(几十M至一两百M),可以在较短时间内完成垃圾收集(几十MS至一百多MS),只要不频繁发生,这是可以接受的 设置参数
添加该参数来显式的使用串行垃圾收集器:"-XX:+UseSerialGC"
收集器(收集器的多线程版本-使用多条线程进行GC)
收集器其实就是收集器的多线程版本,除了使用多线程进行垃圾收集外,其余行为(控制参数、收集算法、回收策略等等)和收集器完全一样 。
它是许多运行在模式下的虚拟机的首要选择,除了收集器外,目前只有它能与CMS收集器配合工作 。
CMS收集器是一个被认为具有划时代意义的并发收集器,因此如果有一个垃圾收集器能和它一起搭配使用让其更加完美,那这个收集器必然也是一个不可或缺的部分了 。
收集器的运行过程如下图所示:
特点应用场景
在模式下,收集器是一个非常重要的收集器,因为除外,目前只有它能与CMS收集器配合工作;
但在单个CPU环境中,不会比收集器有更好的效果,因为存在线程交互开销 。
设置参数
指定使用CMS后,会默认使用ParNew作为新生代收集:"-XX:+UseConcMarkSweepGC"强制指定使用ParNew:"-XX:+UseParNewGC"指定垃圾收集的线程数量,ParNew默认开启的收集线程与CPU的数量相:"-XX:ParallelGCThreads"