共计 4257 个字符,预计需要花费 11 分钟才能阅读完成。
简介
想理解 JDK12,13,14 中的 GC 调优秘籍吗?想晓得这三个版本中 JVM 有什么新的变动吗?
一起来看看这期的 GC 调优秘籍,因为 JDK12,13,14 中的 GC 变动不太大,所以这里一起做个总结,文末附有相应的 PDF 下载,心愿大家可能喜爱。
那些好用的 VM 参数
咱们再讲几个之前的版本中没有讲过的比拟好用的 VM 参数。
-XX:+HeapDumpOnOutOfMemoryError
-XX:HeapDumpPath=path
咱们写 java 程序的,常常会碰到程序报 java.lang.OutOfMemoryError 异样,这时候优良的咱们是怎么解决的呢?
高级程序员一看到这个谬误,就晓得 heap 空间不够用了,加大 heap 空间吧。
然而聪慧的程序员可能就会问了,为什么会呈现这个 OutOfMemoryError 异样呢?是不是咱们程序外面有没有问题呢?
带着这个疑难,聪慧的程序员可能会应用 jmap 命令将 heap dump 进去,甚至有些程序员能够纯熟的应用 jcmd pid GC.heap_info 命令来查看 heap info 了。
这些都很好,然而如果应用下面两个 JVM 选项,程序只有呈现 OutOfMemoryError,就会主动将 heap dump 进去,默认的文件名是 java_pid.hprof,你也能够本人指定文件门路。
-XX:+PrintClassHistogram
有时候,咱们须要统计 class 的信息,那么能够应用这个选项。
在 windows 环境中收到 Control+C,或者在 linux 环境中收到 Control+Break 信号的时候就会触发相应的统计事件。
这个参数和 jmap -histo command 或者 jcmd pid GC.class_histogram 成果是一样的。
有小伙伴要问了,Control+ C 和 Control+Break 信号是什么鬼?怎么将信号传递给 java 程序呢?
这里给大家扩大讲一下,发送信号能够用 kill 命令。
kill 其实有两种用法。
第一种 kill pid,kill 前面间接跟一个 pid。
第二中 kill -TERM pid,TERM 就是咱们要向 kill 传递的信号。
其实 kill pid 就是 kill -15 pid 的简写。
咱们是用 kill - l 来看一下 kill 反对的信号类型:
kill -l
1) SIGHUP 2) SIGINT 3) SIGQUIT 4) SIGILL 5) SIGTRAP
6) SIGABRT 7) SIGBUS 8) SIGFPE 9) SIGKILL 10) SIGUSR1
11) SIGSEGV 12) SIGUSR2 13) SIGPIPE 14) SIGALRM 15) SIGTERM
16) SIGSTKFLT 17) SIGCHLD 18) SIGCONT 19) SIGSTOP 20) SIGTSTP
21) SIGTTIN 22) SIGTTOU 23) SIGURG 24) SIGXCPU 25) SIGXFSZ
26) SIGVTALRM 27) SIGPROF 28) SIGWINCH 29) SIGIO 30) SIGPWR
31) SIGSYS 34) SIGRTMIN 35) SIGRTMIN+1 36) SIGRTMIN+2 37) SIGRTMIN+3
38) SIGRTMIN+4 39) SIGRTMIN+5 40) SIGRTMIN+6 41) SIGRTMIN+7 42) SIGRTMIN+8
43) SIGRTMIN+9 44) SIGRTMIN+10 45) SIGRTMIN+11 46) SIGRTMIN+12 47) SIGRTMIN+13
48) SIGRTMIN+14 49) SIGRTMIN+15 50) SIGRTMAX-14 51) SIGRTMAX-13 52) SIGRTMAX-12
53) SIGRTMAX-11 54) SIGRTMAX-10 55) SIGRTMAX-9 56) SIGRTMAX-8 57) SIGRTMAX-7
58) SIGRTMAX-6 59) SIGRTMAX-5 60) SIGRTMAX-4 61) SIGRTMAX-3 62) SIGRTMAX-2
63) SIGRTMAX-1 64) SIGRTMAX
咱们罕用的 9 =SIGKILL,也就是向 JVM 传递一个强制 kill 的信号。
留神,这些信号中,除了 9 这个信号能够无条件终止过程,其余的信号过程都有权力疏忽。
所以有时候咱们应用 kill pid 命令去终止过程,然而过程没反馈。不是因为过程坏了,而是因为过程疏忽掉了你收回的信号。
-XX:+PrintConcurrentLocks
同样的,PrintConcurrentLocks 也是收到 Control+Break 或者 Control+ C 信号时,输入 java.util.concurrent 的 lock 信息。
这个参数和 jstack -l 或者 jcmd pid Thread.print - l 成果是一样的。
-XX:+PrintFlagsRanges
再来看一个比拟有用的参数 PrintFlagsRanges。有时候咱们想应用某些 VM 的参数,然而不晓得这些参数的取值范畴,那么能够应用 PrintFlagsRanges。咱们试一下:
是不是十分有用?
G1 的变动
JVM 在倒退,G1 的参数也在倒退,这几个版本中有几个 G1 的参数名产生了变动:
-XX:DefaultMaxNewGenPercent 替换成为 -XX:G1MaxNewSizePercent=percent
-XX:G1OldCSetRegionLiveThresholdPercent 替换成为 -XX:G1MixedGCLiveThresholdPercent=percent
-XX:DefaultMinNewGenPercent 替换成为 -XX:G1NewSizePercent=percent
配置 FlightRecorder
Java Flight Recorder(JFR)是 JVM 的诊断和性能剖析工具。它能够收集无关 JVM 以及在其上运行的 Java 应用程序的数据。JFR 是集成到 JVM 中的,所以 JFR 对 JVM 的性能影响十分小,咱们能够释怀的应用它。
一般来说,在应用默认配置的时候,性能影响要小于 1%。
JFR 是一个基于事件的低开销的剖析引擎,具备高性能的后端,能够以二进制格局编写事件。
JFR 是 JVM 的调优工具,通过不停的收集 JVM 和 java 应用程序中的各种事件,从而为后续的 JMC 剖析提供数据。
Event 是由三局部组成的:工夫戳,事件名和数据。同时 JFR 也会解决三种类型的 Event:继续一段时间的 Event,立即触发的 Event 和抽样的 Event。
为了保障性能的最新影响,在应用 JFR 的时候,请抉择你须要的事件类型。
JFR 从 JVM 中收集到 Event 之后,会将其写入一个小的 thread-local 缓存中,而后刷新到一个全局的内存缓存中,最初将缓存中的数据写到磁盘中去。
或者你能够配置 JFR 不写到磁盘中去,然而这样缓存中只会保留局部 events 的信息。
FlightRecorder 有两局部的配置,第一局部是配置 FlightRecorder 自身的大小,存储等信息。第二局部是 FlightRecorder 的开启选项。
咱们看下 FlightRecorder 相干的配置参数:
-XX:FlightRecorderOptions:parameter=value
上面是 StartFlightRecording 的配置:
-XX:StartFlightRecording=parameter=value
RAM 参数
默认状况下,JVM 的 MaxHeapSize 是依据 RAM 的大小来主动配置的,比如说,我有一个 8G 内存的机子, 执行上面的命令:
java -XX:+PrintFlagsFinal -version | grep -Ei "maxheapsize|maxram"
能够看到 MaxHeapSize= MaxRAM / MaxRAMPercentage。
VM 也提供了上面几个用来设置 RAM 相干的参数:
-XX:MaxRAM=size
-XX:InitialRAMPercentage
-XX:MaxRAMPercentage
-XX:MinRAMPercentage
次要就是设置最大的 RAM 值和 Heap 占 RAM 的比例。
RAM 参数次要是为了 java 在容器中运行配置的。
JDK13 中的 ZGC
在 JDK13 中,咱们能够开启 ZGC 的体验了。ZGC 是一个可扩大的,低提早的 GC。ZGC 是并发的,而且不须要进行正在运行的线程。
ZGC 是在 JDK11 中被引入的。
咱们通过上面的形式来开启 ZGC:
-XX:+UnlockExperimentalVMOptions -XX:+UseZGC
RTM 反对
Restricted Transactional Memory(RTM)是受限的事务性存储器,是 Intel 在 x86 微架构中所引入的指令集零碎,它属于 TSX(Transactional Synchronization Extensions,事务性同步扩大)指令集扩大。
RTM 次要用来在多线程环境中晋升执行效率。
RTM 引入了 XBEGIN, XABORT, XEND 和 XTEST。通过将指令蕴含在 XBEGIN 和 XEND 之间,能够达到 transaction 的成果。
能够将 RTM 看做是一个粗粒度的锁,XBEGIN 和 XEND 之间蕴含的代码就是要执行的程序。RTM 能够由硬件自动检测操作中的数据抵触,保障事务性操作的正确性,从而挖掘操作间的并行性。
同时 RTM 还能够缩小 CPU cache line 的 false-sharing。
RTM 反对次要有 4 个参数:
-XX:+UseRTMLocking
-XX:+UseRTMDeopt
-XX:RTMAbortRatio=abort_ratio
-XX:RTMRetryCount=count
其中 UseRTMDeopt 和 RTMAbortRatio 是联结起来用的。
之前咱们讲到 RTM 会对粗粒度的锁进行优化,但如果真的是多线程并发执行拜访同样资源的时候,这个优化实际上是不胜利的,会被 abort,而后回退到失常的锁状态。
如果 abort 超出了肯定的比例,则会将 RTM 代码反优化。
总结
好了,就总结这么多。上面是 JDK12,13,14 的 GC 调优秘籍,欢送下载。
- JDK12GC-cheatsheet.pdf
- JDK13GC-cheatsheet.pdf
- JDK14GC-cheatsheet.pdf
本文作者:flydean 程序那些事
本文链接:http://www.flydean.com/jdk12-13-14-gc-cheatsheet/
本文起源:flydean 的博客
欢送关注我的公众号: 程序那些事,更多精彩等着您!