JVM学习日记⭐️HotSpot垃圾收集器(下)⭐️

581 阅读4分钟

“这是我参与8月更文挑战的第22天,活动详情查看:8月更文挑战

🔉引言

接下来,把剩下的垃圾收集器都肝完。

⭐️经典的垃圾收集器

🌟SerialOld收集器

SerialOld收集器是Serial的老年代版本,单线程,使用标记整理算法,在服务端模式下,有2种用途:图如下。

  • Parallel Scavenge收集器配合使用(JDK5以前)
  • 作为CMS收集失败的预案

image.png

🌟ParallelOld收集器

ParallelOld收集器是Parallel Scavenge的老年代版本,多线程,使用标记整理算法实现,直到JDK6才提供,在以前啊,你要是新生代使用Parallel Scavenge那就会比较尴尬,为啥呢?因为老年代除了SerialOld你找不到与它配合的了,但由于SerialOld在服务器上性能的拖累,导致使用Parallel Scavenge起不到很好的吞吐量效果,另一方面,由于单线程无法充分使用服务器的并行处理能力,导致组合起来还不一定有ParNewCMS组合的效果更优一些。

那在ParallelOld收集器出现后,这种尴尬场面就没有了,牛郎还是得配织女才行,咳咳。那在吞吐量优先或者处理器资源较为稀缺的场合,我们就可以优先考虑它了,图如下。

image.png

🌟CMS收集器

CMS收集器英文名是Concurrent mark sweep,以最短停顿时间为最终目标,适用于一些延时要求低的应用,这类应用的系统停顿时间尽可能短,以便给用户带来很好的交互体验。

Mark Sweep 一看就知道是基于标记-清除算法的,整个过程一共是4个步骤:

  • 初始标记(CMS inital mark
  • 并发标记(CMS inital mark
  • 重新标记 (CMS remark
  • 并发清除(Concurrent sweep

其中初始标记和并发标记,是需要Stop the world的,初始标记的速度很好,只需要标记与GCRoots关联的对象就好,并发标记那就耗时较长了,肝什么呢?就把GCRoots关联的对象都遍历一遍,但不需要暂停用户线程,由于是并发操作,所以难免会出现增量更新的情况,关于增量更新可以点击(传送门)去看看。

最后一步就是清除了,由于不需要暂停用户线程,不需要移动存活对象,所以操作也是并发的,图如下。

image.png

CMS收集器的缺点

  • 对处理器资源敏感
  • 容易产生浮动垃圾
  • 容易产生空间碎片

面向并发设计的程序都对处理器资源比较敏感,因为要抽调一部分资源去肝额外的事情,虽不会导致用户线程的停顿,但会占用一部分处理器的处理能力,就会使程序变慢,降低总吞吐量。如果你处理器的核心数多,那当然没问题,但如果核心数低,甚至不足4个时,那影响就会大了,可能会导致用户程序忽然变得很慢,那为了解决这种情况,虚拟机提供了一种增量式的并发收集器,在并发收集和标记时,动态的交替运行,尽量减少垃圾线程的占用时间。这样虽然延长了垃圾回收的时间,但是对程序的影响就很小了,那理论是很好的,实际并不是很好,所以JDK9就废弃了。

接下来说第二点,就是由于操作的并行的嘛,用户线程就会持续的产生垃圾,但是有的垃圾出现在标记过程结束后,那就不能在这一阶段回收,这部分就是漏网之鱼了。同样,为了保证用户线程持续运行,就不能等待老年代满才进行垃圾收集,而是要预留一部分内存供并发收集的程序使用,如果预留的程序内存无法满足对象分配的需要,就会出现并发失败的结果,这时虚拟机就会冻结用户线程,使用Serial Old,这样停顿时间就比较长了。

最后一个介绍过了,想了解的小伙伴可以点击【传送门】。

📝题外话

最受爱戴的人应该是那些对于改善人类和人类生活最有贡献的人。这在原则上讲应该是对的。但是,如果你进一步问这类人是谁,就会遇到不小的麻烦。对于政治领袖,甚至宗教领袖,他们究竟是为善多还是作恶多,向来难以定论。

因此我非常真诚地相信,为社会大众提供最好服务的人,是为大众提供可以用来自我升华的工作,从而间接使人臻于完善的人。这首先适用于伟大的艺术家,其次也适用于科学家。无疑,提升人的思想境界并丰富其内在本质的,并非研究成果,而是追求理解的动力,是那种创造性和感受性的脑力劳动。

第22天,大家加油!