简介
明天咱们讲讲 JDK10 中的 JVM GC 调优参数,JDK10 中 JVM 的参数总共有 1957 个,其中正式的参数有 658 个。
其实 JDK10 跟 JDK9 相比没有太大的变动,一个咱们能够感触到的变动就是引入了本地变量 var。
为了不便大家的参考,特意将 JDK10 中的 GC 参数总结成了一张 PDF,这个 PDF 在之前的 JDK9 的根底上进行了增减和修改,欢送大家下载。
Java 参数类型
其实 Java 参数类型能够分为三类。
第一类叫做规范的 java 参数。
这一类参数是被所有的 JVM 实现所反对的,是一些十分罕用的 JVM 参数。
咱们能够通过间接执行 java 命令来查看。
第二类叫做额定的 java 参数,这些参数是专门为 Hotspot VM 筹备的,并不保障所有的 JVM 都实现了这些参数。并且这些参数随时有可能被批改。额定的 java 参数是以 - X 结尾的。
咱们能够通过 java - X 来查看。
第三类叫做高级参数。这些参数是开发者选项,次要作用就是 JVM 调优。这些参数和第二类参数一样,也是不保障被所有的 JVM 反对的,并且随时都可能变动。
第三类参数是以 -XX 结尾的,咱们能够通过 java -XX:+PrintFlagsFinal 来查看。
神奇的是,咱们做 JVM 调优的参数往往就是这第三类参数,所以,下次如果再有面试官问你 JVM 调优,你能够间接怼回去:这些参数是不被官网举荐一般使用者应用的,并且随时都可能变动。没必要把握!那么这个 Offer 必定非你莫属。
Large Pages
其实 JDK10 跟 JDK9 相比没啥大的变动,这里重点解说一个个性叫做 Large Pages。
Large pages 其实不是 JDK10 的新个性了,它的历史曾经很久了。
在讲 large Pages 之前,咱们先讲一下内存分页。
CPU 是通过寻址来拜访内存空间的。一般来说 CPU 的寻址能力是无限的。而理论的物理内存地址会远大于 CPU 的寻址范畴。
为了解决这个问题,古代 CPU 引入了 MMU(Memory Management Unit 内存治理单元) 和虚拟地址空间的概念。
虚拟地址空间也叫做(Virtual address space),为了不同程序的相互隔离和保障程序中地址的确定性,古代计算机系统引入了虚拟地址空间的概念。简略点讲能够看做是跟理论物理地址的映射,通过应用分段或者分页的技术,将理论的物理地址映射到虚拟地址空间。
同时为了解决虚拟空间比物理内存空间大的问题,古代计算机技术个别都是用了分页技术。
分页技术就是将虚拟空间分为很多个 page,只有在须要用到的时候才为该 page 调配到物理内存的映射,这样物理内存实际上能够看做虚拟空间地址的缓存。
虚拟地址空间和物理地址的映射是通过一个叫做映射存储表的中央来工作的。这个中央个别被叫做页表 (page table),页表是存储在物理内存中的。
CPU 读取物理内存速度必定会慢于读取寄存器的速度。于是又引入了 TLB 的概念。
Translation-Lookaside 缓冲区(TLB)是一个页面转换缓存,其中保留了最近应用的虚构到物理地址转换。
TLB 容量是无限的。如果产生 TLB miss 则须要 CPU 去拜访内存中的页表,从而造成性能损耗。
通过调大内存分页大小,单个 TLB 条目存储更大的内存范畴。这将缩小对 TLB 的压力,并且对内存密集型应用程序可能具备更好的性能。
然而,大页面也可能会对系统性能产生负面影响。例如,当应用程序应用大量大页面内存时,可能会导致惯例内存不足,并导致其余应用程序中的过多分页,并使整个零碎变慢。同样,长时间运行的零碎可能会产生过多的碎片,这可能导致无奈保留足够大的页面内存。产生这种状况时,OS 或 JVM 都会复原为应用惯例页面。
Oracle Solaris, Linux, and Windows Server 2003 都反对大页面。
具体各个系统的 large page 的配置,大家能够自行摸索。
JIT 调优
JIT 我在之前的文章中介绍过很屡次了,为了晋升 java 程序的执行效率,JVM 会将局部热点代码,应用 JIT 编译成为机器码。
那么 JIT 的调试参数也是十分重要的。这里具体解说一些比拟罕用 JIT 调试指令:
-XX:+BackgroundCompilation
应用后盾编译,也就是说编译线程和前台线程应用是不同的线程。一般来说如果咱们须要调试 JIT 日志的话,须要敞开此选项。
-XX:CICompilerCount=threads
设置编译线程的个数。
-XX:CompileCommand=command,method[,option]
自定义具体方法的编译形式。
比方:
-XX:CompileCommand=exclude,java/lang/String.indexOf
意思是把 String 的 indexOf exclude from compiled。
这里的 command 有上面几种:
- break – 为编译设置断点
- compileonly – exclude 所有的办法,除了指定的办法
- dontinline – 指定的办法不 inline
- exclude – 编译的时候排除指定的办法
- inline – inline 指定的办法
- log – exclude 所有的办法日志,除了指定的办法
- option – 传递一个 JIT 编译的参数
- print – 输入生成的汇编代码
- quiet – 不打印编译命令
-XX:CompileOnly=methods
指定编译某些命令。
-XX:CompileThreshold=invocations
命令通过多少次解释执行,才会被编译。默认状况下在 -server 模式,这个值是 10,000,在 -client 模式,这个值是 1,500。
如果分层编译开启之后,这个值会被疏忽。
-XX:+DoEscapeAnalysis
开启逃逸剖析。
-XX:+Inline
开启 inline 个性。
-XX:+LogCompilation
输入编译日志。
-XX:+PrintAssembly
输入汇编代码。
-XX:-TieredCompilation
勾销分层编译。
上图:
总结
同样的,为 JDK10 特意筹备了一个 PDF,下载链接如下:
JDK10GC-cheatsheet.pdf
本文链接:http://www.flydean.com/jdk10-gc-cheatsheet/
最艰深的解读,最粗浅的干货,最简洁的教程,泛滥你不晓得的小技巧等你来发现!
欢送关注我的公众号:「程序那些事」, 懂技术,更懂你!