萌新小白看完JVM垃圾处理器的笔记,只是大概的描述一下垃圾处理器的几种,以及使用到的算法、运行过程和其缺陷。
经典的垃圾收集器(技术咨询vx:keyichen_free)
1.Serial收集器
显而易见,这是一个单线程的收集器,其意义包括它只会使用一个处理器或一个收集线程去完成垃圾处理工作,和它在进行垃圾处理的过程中,必须暂停其它的工作任务,直到它收集结束。
Serial在对垃圾进行收集的时候,由虚拟机在后台自动发起和自动完成的,在用户不可知、不可控的情况下,把用户的正常工作全部停掉。这对用户人来说是无法接受的,试想,你游戏没玩半小时就会暂停响应五分钟。
但是迄今为止,Serial收集器仍然是HotSpot虚拟机运行在客户端模式下的默认新生代收集器,有着比其他收集器优越的地方,那就是简单高效,对于内存资源受限的环境,它是所有收集器里额外内存消耗最少的。
2.ParNew收集器
ParNew收集器实质上就是Serial收集器的多线程版本,处理同时使用多条线程进行垃圾收集之外,其他的所控制参数、收集算法等都与Serial一致。
ParNew收集器是不少运行在服务端模式下的HotSpot虚拟机。
JDK5发布的的时候,HotSpot推出了具有跨时代意义的收集器,CMS收集器。实现了让垃圾收集线程和用户线程(基本上)同时工作
3.Parallel Scavenge收集器
Parallel Scavenge收集器是一款新生代收集器。它是基于标记-复制算法来实现的(前面文章有对其进行讲解)
Parallel Scavenge收集器的特点在于它的关注点与其他的收集器不同,CMS等收集器的关注点是尽可能地缩短垃圾收集时用户线程的停顿时间,而Parallel Scavenge收集器的目标则是达到一个可控制的吞吐量。
吞吐量:指的是处理器用于运行用户代码的时间与处理器总消耗的时间之比。虚拟机总共运行了100分钟,其中垃圾收集花掉1分钟,那吞吐量就是99%。
吞吐量 = 运行用户代码时间 / ( 运行用户代码时间 + 运行垃圾收集时间 )
Parallel Scavenge收集器提供了两个参数用于精确控制吞吐量,分别是控制最大垃圾收集停顿时间的-XX:MaxGCPauseMillis参数以及直接设置吞吐量大小的-XX:GCTimeRatio参数。
4.Serial Old收集器
Serial Old收集器是Serial 收集器的老年代版本,同样为一个单线程收集器,使用的是标记-整理的算法。
这个收集器主要是供客户端模式下的HotSpot虚拟机使用,
5.Parallel Old 收集器
Parallel Old 收集器是Parallel Scavenge收集器的老年代版本,支持多线程和并发收集,基于标记-整理算法是实现。
6.CMS收集器
CMS收集器是一款以获取最短回收停顿时间为目标的收集器。基于的是标记-清除算法来实现
运行过程相对于前几个收集器复杂一些:
- 初始标记
- 并发标记
- 重新标记
- 并发清除
其中初始标记、重新标记这两个步骤仍然需要 “Stop the World”。
从总体上来说,CMS收集器内存回收过程是与用户线程一起并发执行的。
CMS收集器的缺陷:
-
CMS收集器对于处理器的资源非常敏感。在并发阶段,虽然不会导致用户线程停顿,但却会因为占用了一部分线程而导致应用程序变慢,降低吞吐量。
-
CMS收集器无法处理“浮动垃圾”。
-
由于它是基于标记-清除算法来实现的,那么从前面文章可知,该算法意味着收集结束的时候会产生大量的空间碎片。空间碎片过多的时候,将会给大对象分配带来很大的麻烦。
7.Garbage First收集器
G1只要是一款面向服务端应用的垃圾处理器。
在之前的收集器中,垃圾收集的目标范围要么是新生代,要么是老生代。而G1收集器却不是这样,它跳出了这个范围,可面向堆内存任何部分来组成回收集进行回收,衡量标准不再是他属于哪个分代,而是哪块内存中存放的垃圾数量最多,回收收益最大,这就是G1的Mixed模式。
G1收集器的运行过程大致分为以下四个步骤:
- 初始标记
- 并发标记
- 最终标记
- 筛选回收
G1收集器除了并发标记,其余阶段也是要完全暂停用户线程。
从G1开始,最先进的垃圾收集器的设计导向不约而同地变为了追求能够应付应用的内存分速率,不再追求一次吧Java的堆全部清理干净。
8.并发和并行的补充
并行:描述的是多条垃圾收集线程之间的关系,默认此时用户处于等待状态
并发:描述的多条垃圾收集器与用户线程之间的关系,说明同一时间垃圾收集器线程与用户线程都在运行。由于用户线程并未被冻结,所有程序仍然可以响应服务请求。
低延迟的垃圾收集器
1,Shenandoah收集器
Shenandoah收集器是一款不是Oracle公司的虚拟机团队所领导开发的HotSpot垃圾处理器
它更像是G1的下一代继承者。有着与G1至少三个明显的不同之处
- 支持并发的整理算法,G1在回收阶段是可以并行的,但是却不能与用户线程并行
- Shenandoah收集器目前默认不使用分代收集
- Shenandoah收集器摒弃了G1中消耗大量内存和计算资源去维护的记忆集,改名为“连接矩阵”的全局数据结构来记录夸Region的引用关系,降低了处理跨带指针时的记忆集维护消耗,也降低了伪共享问题的发生概率。
它有以下9个运行阶段:
- 初始标记
- 并发标记
- 最终标记
- 并发处理
- 并发回收
- 初始引用更新
- 并发引用更新
- 最用引用更新
- 并发清理
2.ZGC收集器
ZGC收集器的目标和Shenandoah收集器目标高度相似,都是希望在尽可能对吞吐量影响不大的情况下,实现在任意堆内存大小下都可以把垃圾收集的停顿时间限制在10毫秒以下的低延迟。
ZGC的核心:并发整理算法的实现。使用转发指针和读屏障来实现并发整理
ZGC收集器有一个标志性的设计就是它采用的染色指针技术。
ZGC的三大优势:
- 染色指针可以使得一旦某一个Rigion的存活对象被移走后,这个Rigion立即就能够被释放和重用掉,而不必等待整个堆中所有指向该Rigion的引用都被修正后才能清理。
- 染色指针可以大幅度减少在垃圾收集过程中内屏障的的使用数量,设置内屏障,尤其是写屏障的目的通常是为了记录对象引用的变动情况,如果这些信息直接维护在指针中,显然就可以省去专门的记录操作。
- 染色指针可以作为一种可扩展的存储结构用来记录更多与对象标记、重定位过程中相关的数据,以便日后进一步提高性能。
ZGC收集器的运行阶段:
-
并发标记
-
并发预备重分配
-
并发重分配
-
并发重映射
就可以省去专门的记录操作。
3. 染色指针可以作为一种可扩展的存储结构用来记录更多与对象标记、重定位过程中相关的数据,以便日后进一步提高性能。
ZGC收集器的运行阶段:
-
并发标记
-
并发预备重分配
-
并发重分配
-
并发重映射