炸了!一口气问了我18个JVM问题!

GC 对于Java 来说重要性不言而喻,不论是平日里对 JVM 的调优还是面试中的无情轰炸。

这篇文章我会以一问一答的方式来展开有关 GC 的内容。

不过在此之前强烈建议先看这篇文章深度揭秘垃圾回收底层。

因为这篇文章解释了很多有关垃圾回收的基本知识,能从源头上理解垃圾回收和日益发展的垃圾收集器演进的方向,这很重要

本文章所说的 GC 实现没有特殊说明的话,默认指的是 HotSpot 的。

我先将十八个问题都列出来,如果都清楚的话那就可以关闭这篇文章了。

炸了!一口气问了我18个JVM问题!

好了,开始表演。

young gc、old gc、full gc、mixed gc 傻傻分不清?

这个问题的前置条件是你得知道 GC 分代,为什么分代。这个在之前文章提了,不清楚的可以去看看。

现在我们来回答一下这个问题。

其实 GC 分为两大类,分别是 Partial GC 和 Full GC。

Partial GC 即部分收集,分为 young gc、old gc、mixed gc。

young gc:指的是单单收集年轻代的 GC。

old gc:指的是单单收集老年代的 GC。

mixed gc:这个是 G1 收集器特有的,指的是收集整个年轻代和部分老年代的 GC。

Full GC 即整堆回收,指的是收取整个堆,包括年轻代、老年代,如果有永久代的话还包括永久代。

其实还有 Major GC 这个名词,在《深入理解Java虚拟机》中这个名词指代的是单单老年代的 GC,也就是和 old gc 等价的,不过也有很多资料认为其是和 full gc 等价的。

还有 Minor GC,其指的就是年轻代的 gc。

young gc 触发条件是什么?

大致上可以认为在年轻代的 eden 快要被占满的时候会触发 young gc。

为什么要说大致上呢?因为有一些收集器的回收实现是在 full gc 前会让先执行以下 young gc。

比如 Parallel Scavenge,不过有参数可以调整让其不进行 young gc。

可能还有别的实现也有这种操作,不过正常情况下就当做 eden 区快满了即可。

eden 快满的触发因素有两个,一个是为对象分配内存不够,一个是为 TLAB 分配内存不够。

full gc 触发条件有哪些?

这个触发条件稍微有点多,我们来看下。

在要进行 young gc 的时候,根据之前统计数据发现年轻代平均晋升大小比现在老年代剩余空间要大,那就会触发 full gc。

有永久代的话如果永久代满了也会触发 full gc。

老年代空间不足,大对象直接在老年代申请分配,如果此时老年代空间不足则会触发 full gc。

担保失败即 promotion failure,新生代的 to 区放不下从 eden 和 from 拷贝过来对象,或者新生代对象 gc 年龄到达阈值需要晋升这两种情况,老年代如果放不下的话都会触发 full gc。

执行 System.gc()、jmap -dump 等命令会触发 full gc。

知道 TLAB 吗?来说说看

这个得从内存申请说起。

一般而言生成对象需要向堆中的新生代申请内存空间,而堆又是全局共享的,像新生代内存又是规整的,是通过一个指针来划分的。

炸了!一口气问了我18个JVM问题!

内存是紧凑的,新对象创建指针就右移对象大小 size 即可,这叫指针加法(bump [up] the pointer)。

可想而知如果多个线程都在分配对象,那么这个指针就会成为热点资源,需要互斥那分配的效率就低了。

于是搞了个 TLAB(Thread Local Allocation Buffer),为一个线程分配的内存申请区域。

这个区域只允许这一个线程申请分配对象,允许所有线程访问这块内存区域

TLAB 的思想其实很简单,就是划一块区域给一个线程,这样每个线程只需要在自己的那亩地申请对象内存,不需要争抢热点指针。

当这块内存用完了之后再去申请即可。

这种思想其实很常见,比如分布式发号器,每次不会一个一个号的取,会取一批号,用完之后再去申请一批。

炸了!一口气问了我18个JVM问题!

可以看到每个线程有自己的一块内存分配区域,短一点的箭头代表 TLAB 内部的分配指针。

如果这块区域用完了再去申请即可。

不过每次申请的大小不固定,会根据该线程启动到现在的历史信息来调整,比如这个线程一直在分配内存那么 TLAB 就大一些,如果这个线程基本上不会申请分配内存那 TLAB 就小一些。

还有 TLAB 会浪费空间,我们来看下这个图。

炸了!一口气问了我18个JVM问题!

可以看到 TLAB 内部只剩一格大小,申请的对象需要两格,这时候需要再申请一块 TLAB ,之前的那一格就浪费了。

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/wpxpzg.html