简介
JVM 的参数有很多很多, 根据我的统计 JDK8 中 JVM 的参数总共有 1853 个,正式的参数也有 680 个。
这么多参数带给我们的是对 JVM 的细粒度的控制,但是并不是所有的参数都需要我们自己去调节的,我们需要关注的是一些最常用的,对性能影响比较大的 GC 参数即可。
为了更好的让大家理解 JDK8 中 GC 的调优的秘籍,这里特意准备了八张图。在本文的最后,还附带了一个总结的 PDF all in one 文档,大家把 PDF 下载回去,遇到问题就看两眼,不美吗?
分代垃圾回收器的内存结构
为了更好的提升 GC 的效率,现代的 JVM 都是采用的分代垃圾回收的策略(ZGC 不是)。
java 运行时内存可以分为 JVM 内存和非 JVM 内存。
JVM 内存又可以分为堆内存和非堆内存。
堆内存大家都很熟悉了,YoungGen 中的 Eden,Survivor 和 OldGen。
非堆内存中存储的有 thread Stack,Code Cache, NIO Direct Buffers,Metaspace 等。
注意这里的 Metaspace 元空间是方法区在 JDK8 的实现,它是在本地内存中分配的。
JDK8 中可用的 GC
JDK8 中到底有哪些可以使用的 GC 呢?
这里我们以 HotSpot JVM 为例,总共可以使用 4 大 GC 方式:
其中对于 ParallelGC 和 CMS GC 又可以对年轻代和老年代分别设置 GC 方式。
大家看到上图可能有一个疑问,Parallel scavenge 和 Parallel 有什么区别呢?
其实这两个 GC 的算法是类似的,Parallel Scavenge 收集器也经常称为“吞吐量优先”收集器,Parallel Scavenge 收集器提供了两个参数用于精确控制吞吐量; -XX:MaxGCPauseMillis:控制最大垃圾收集停顿时间; -XX:GCTimeRatio:设置吞吐量大小。
同时 Parallel Scavenge 收集器能够配合自适应调节策略,把内存管理的调优任务交给虚拟机去完成。
GDK8 中默认开启的是 ParallelGC。
打印 GC 信息
如果想研究和理解 GC 的内部信息,GC 信息打印是少不了的:
上图提供了一些非常有用的 GC 日志的控制参数。
内存调整参数
JVM 分为 Heap 区和非 Heap 区,各个区又有更细的划分,下面就是调整各个区域大小的参数:
Thread 配置
TLAB 大家还记得吗?
如果一个对象的分配是在方法内部,并且没有多线程访问的情况下,那么这个对象其实可以看做是一个本地对象,这样的对象不管创建在哪里都只对本线程中的本方法可见,因此可以直接分配在栈空间中。
栈上分配的对象因为不用考虑同步,所以执行速度肯定会更加快速,这也是为什么 JVM 会引入栈上分配的原因。
上图就是 TLAB 的参数。
通用 GC 参数
虽然 JDK8 的 GC 这么多,但是他们有一些通用的 GC 参数:
这里讲解一下 Young space tenuring,怎么翻译我不是很清楚,这个主要就是指 Young space 中的对象经过多少次 GC 之后会被提升到 Old space 中。
CMS GC
CMS 全称是 Concurrent mark sweep。是一个非常非常复杂的 GC。
复杂到什么程度呢?光光是 CMS 调优的参数都有一百多个!
下图是常用的 CMS 的参数。
CMS 这里就不多讲了,因为在 GDK9 之后,CMS 就已经被废弃了。
主要原因是 CMS 太过复杂,如果要向下兼容需要巨大的工作量,然后就直接被废弃了。
在 GDK9 之后,默认的 GC 是 G1。
G1 参数
G1 收集器是分代的和 region 化的,也就是整个堆内存被分为一系列大小相等的 region。在启动时,JVM 设置 region 的大小,根据堆大小的不同,region 的大小可以在 1MB 到 32MB 之间变动,region 的数量最多不超过 2048 个。Eden 区、Survivor 区、老年代是这些 region 的逻辑集合,它们并不是连续的。
G1 中的垃圾收集过程:年轻代收集和混合收集交替进行,背后有全局的并发标记周期在进行。当老年代分区占用的空间达到或超过初始阈值,就会触发并发标记周期。
下图是 G1 的调优参数:
总结
上面总共 8 副图,我把他们做成了一个 PDF,预览界面大概是这样子的:
大家可以通过下面的链接直接下载 PDF 版本:
JDK8GC-cheatsheet.pdf
如果遇到问题可以直接拿过来参考。这种东西英文名字应该叫 JDK8 GC cheatsheet,翻译成中文应该就是 JDK8 GC 调优秘籍!
本文作者:flydean 程序那些事
本文链接:http://www.flydean.com/jdk8-gc-cheatsheet/
本文来源:flydean 的博客
欢迎关注我的公众号: 程序那些事,更多精彩等着您!