༺歲月蹉跎༻

只要路是对的,就不怕路远!

0%

JVM性能监控

1、JVM监控及诊断工具-命令行

1.1 概述

  • 性能诊断是软件工程师在日常工作中需要经常面对和解决的问题,在用户体验至上的今天,解决好应用的性能问题能带来非常大的收益。

  • Java 作为最流行的编程语言之一,其应用性能诊断一直受到业界广泛关注。可能造成 Java 应用出现性能问题的因素非常多,例如线程控制、磁盘读写、数据库访问、网络I/O、垃圾收集等。想要定位这些问题,一款优秀的性能诊断工具必不可少。

  • 简单命令行工具:在我们刚接触java学习的时候,大家肯定最先了解的两个命令就是javac,java,那么除此之外,还有没有其他的命令可以供我们使用呢?我们进入到安装jdk的bin目录,发现还有一系列辅助工具。这些辅助工具用来获取目标 JVM 不同方面、不同层次的信息,帮助开发人员很好地解决Java应用程序的一些疑难杂症。

1.2 jps:查看正在运行的Java进程

1.2.1 基本情况

  • jps(Java Process Status):显示指定系统内所有的HotSpot虚拟机进程(查看虚拟机进程信息),可用于查询正在运行的虚拟机进程。

  • 说明:对于本地虚拟机进程来说,进程的本地虚拟机ID与操作系统的进程ID是一致的,是唯一的。

1.2.2 基本语法

  • 它的基本使用语法为:jps [options] [hostid]
  • 我们还可以通过追加参数,来打印额外的信息。

options参数

  • -q :仅仅显示LVMID (local virtual machine id),即本地虚拟机唯一id。不显示主类的名称等。

  • -l: 输出应用程序主类的全类名 或 如果进程执行的是jar包,则输出jar完整路径。

  • -m: 输出虚拟机进程启动时传递给主类main()的参数。

  • -v: 列出虚拟机进程启动时的JVM参数。 比如:-Xms20m -Xmx50m是启动程序指定的jvm参数。

  • 如果某 Java 进程关闭了默认开启的UsePerfData参数(即使用参数-XX:-UsePerfData),那么jps命令(以及下面介绍的jstat)将无法探知该 Java 进程。

hostid参数

  • RMI注册表中注册的主机名。

  • 如果想要远程监控主机上的 java 程序,需要安装 jstatd。

  • 对于具有更严格的安全实践的网络场所而言,可能使用一个自定义的策略文件来显示对特定的可信主机或网络的访问,尽管这种技术容易受到IP地址欺诈攻击

  • 如果安全问题无法使用一个定制的策略文件来处理,那么最安全的操作是不运行jstatd服务器,而是在本地使用jstat和jps工具。

1.3 jstat:查看JVM统计信息

1.3.1 基本情况

  • jstat(JVM Statistics Monitoring Tool):用于监视虚拟机各种运行状态信息的命令行工具。它可以显示本地或者远程虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据。

  • 在没有GUI图形界面,只提供了纯文本控制台环境的服务器上,它将是运行期定位虚拟机性能问题的首选工具。常用于检测垃圾回收问题以及内存泄漏问题。

  • jstat还可以用来判断是否出现内存泄漏。

    • 第1步:在长时间运行的 Java 程序中,我们可以运行jstat命令连续获取多行性能数据,并取这几行数据中 OU 列(即已占用的老年代内存)的最小值。
    • 第2步:然后,我们每隔一段较长的时间重复一次上述操作,来获得多组 OU 最小值。如果这些值呈上涨趋势,则说明该 Java 程序的老年代内存已使用量在不断上涨,这意味着无法回收的对象在不断增加,因此很有可能存在内存泄漏。
  • 官方文档:https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstat.html

1.3.2 基本语法

  • 它的基本使用语法为:jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]]

  • 查看命令相关参数:jstat -hjstat -help

option参数:选项option可以由以下值构成。

  • 类装载相关的:

    • -class:显示ClassLoader的相关信息:类的装载、卸载数量、总空间、类装载所消耗的时间等。
  • 垃圾回收相关的:

    • -gc:显示与GC相关的堆信息。包括Eden区、两个Survivor区、老年代、永久代等的容量、已用空间、GC时间合计等信息。

      • 新生代相关
        • S0C是第一个幸存者区的大小(字节)
        • S1C是第二个幸存者区的大小(字节)
        • S0U是第一个幸存者区已使用的大小(字节)
        • S1U是第二个幸存者区已使用的大小(字节)
        • EC是Eden空间的大小(字节)
        • EU是Eden空间已使用大小(字节)
      • 老年代相关
        • OC是老年代的大小(字节)
        • OU是老年代已使用的大小(字节)
      • 方法区(元空间)相关
        • MC是方法区的大小
        • MU是方法区已使用的大小
        • CCSC是压缩类空间的大小
        • CCSU是压缩类空间已使用的大小
      • 其它
        • YGC是指从应用程序启动到采样时young gc次数
        • YGCT是指从应用程序启动到采样时young gc消耗的时间(秒)
        • FGC是指从应用程序启动到采样时full gc次数
        • FGCT是指从应用程序启动到采样时full gc消耗的时间(秒)
        • GCT是指从应用程序启动到采样时gc的总时间
    • -gccapacity:显示内容与-gc基本相同,但输出主要关注Java堆各个区域使用到的最大、最小空间。

    • -gcutil:显示内容与-gc基本相同,但输出主要关注已使用空间占总空间的百分比。

    • -gccause:与-gcutil功能一样,但是会额外输出导致最后一次或当前正在发生的GC产生的原因。

    • -gcnew:显示新生代GC状况。

    • -gcnewcapacity:显示内容与-gcnew基本相同,输出主要关注使用到的最大、最小空间。

    • -geold:显示老年代GC状况。

    • -gcoldcapacity:显示内容与-gcold基本相同,输出主要关注使用到的最大、最小空间。

    • -gcpermcapacity:显示永久代使用到的最大、最小空间。

  • JIT相关的:

    • -compiler:显示JIT编译器编译过的方法、耗时等信息。
    • -printcompilation:输出已经被JIT编译的方法。

interval参数

  • 用于指定输出统计数据的周期,单位为毫秒。即:查询间隔。

count参数

  • 用于指定查询的总次数。

-t参数

  • 可以在输出信息前加上一个Timestamp列,显示程序的运行时间。单位:秒。
    • 我们可以比较 Java 进程的启动时间以及总 GC 时间(GCT 列),或者两次测量的间隔时间以及总 GC 时间的增量,来得出 GC 时间占运行时间的比例。
    • 如果该比例超过 20%,则说明目前堆的压力较大;如果该比例超过 90%,则说明堆里几乎没有可用空间,随时都可能抛出 OOM 异常。

-h参数

  • 可以在周期性数据输岀时,输出多少行数据后输出一个表头信息。

1.4 jinfo:实时查看和修改JVM配置参数

1.4.1 基本情况

  • jinfo(Configuration Info for Java):查看虚拟机配置参数信息,也可用于调整虚拟机的配置参数。

  • 在很多情况下,Java应用程序不会指定所有的Java虚拟机参数。而此时,开发人员可能不知道某一个具体的Java虚拟机参数的默认值。在这种情况下,可能需要通过查找文档获取某个参数的默认值。这个査找过程可能是非常艰难的。但有了jinfo工具,开发人员可以很方便地找到Java虚拟机参数的当前值。

  • 官方帮助文档:https://docs.oracle.com/en/java/javase/11/tools/jinfo.html

1.4.2 基本语法

  • 它的基本使用语法为:jinfo [ options ] pid

    • 说明:java 进程ID 必须要加上。

    image-20240303144847205

查看

  • jinfo -sysprops PID:可以查看由System.getProperties()取得的参数。
  • jinfo -flags PID:查看曾经赋过值的一些参数。
  • jinfo -flag 具体参数 PID:查看某个java进程的具体参数的值。

修改

  • jinfo不仅可以查看运行时某一个Java虚拟机参数的实际取值,甚至可以在运行时修改部分参数,并使之立即生效。

  • 但是,并非所有参数都支持动态修改。参数只有被标记为manageable的flag可以被实时修改。其实,这个修改能力是极其有限的。可以查看被标记为manageable的参数:java -XX:+PrintFlagsFinal -version | grep manageable

    image-20240303145140766

  • 针对boolean类型:jinfo -flag [+|-]具体参数 PID

  • 针对非boolean类型:jinfo -flag 具体参数=具体参数值 PID

1.4.3 拓展

  • java -XX:+PrintFlagsInitial:查看所有JVM参数启动的初始值。
  • java -XX:+PrintFlagsFinal:查看所有JVM参数的最终值。
  • java -XX:+PrintCommandLineFlags:查看那些已经被用户或者JVM设置过的详细的XX参数的名称和值。

1.5 jmap:导出内存映像文件&内存使用情况

1.5.1 基本情况

  • jmap(JVM Memory Map):作用一方面是获取dump文件(堆转储快照文件,二进制文件),它还可以获取目标Java进程的内存相关信息,包括Java堆各区域的使用情况、堆中对象的统计信息、类加载信息等。

  • 开发人员可以在控制台中输入命令“jmap -help”查阅jmap工具的具体使用方式和一些标准选项配置。

  • 官方帮助文档:https://docs.oracle.com/en/java/javase/11/tools/jmap.html

1.5.2 基本语法

  • 它的基本使用语法为:

    • jmap [option] <pid>
    • jmap [option] <executable <core>
    • jmap [option] [server_id@]<remote server IP or hostname>
  • 其中option包括:

    image-20240303145645102

    • 说明:这些参数和linux下输入显示的命令多少会有不同,包括也受jdk版本的影响。

-dump

  • 生成Java堆转储快照:dump文件。

  • 特别的:-dump:live只保存堆中的存活对象。

-heap

  • 输出整个堆空间的详细信息,包括GC的使用、堆配置信息,以及内存的使用信息等。

-histo

  • 输出堆中对象的统计信息,包括类、实例数量和合计容量。
  • 特别的:-histo:live只统计堆中的存活对象。

-permstat

  • 以ClassLoader为统计口径输出永久代的内存状态信息。
  • 仅linux/solaris平台有效。

-finalizerinfo

  • 显示在F-Queue中等待Finalizer线程执行finalize方法的对象。
  • 仅linux/solaris平台有效。

-F

  • 当虚拟机进程对-dump选项没有任何响应时,可使用此选项强制执行生成dump文件。
  • 仅linux/solaris平台有效。

-h | -help

  • jmap工具使用的帮助命令。

-J <flag>

  • 传递参数给jmap启动的jvm。

1.5.3 使用1:导出内存映像文件

  • 手动的方式

    • jmap -dump:format=b,file=<filename.hprof> <pid>
    • jmap -dump:live,format=b,file=<filename.hprof> <pid>
  • 自动的方式

    • 当程序发生OOM退出系统时,一些瞬时信息都随着程序的终止而消失,而重现OOM问题往往比较困难或者耗时。此时若能在OOM时,自动导出dump文件就显得非常迫切。这里介绍一种比较常用的取得堆快照文件的方法,即使用:

      • -XX:+HeapDumpOnOutOfMemoryError:在程序发生OOM时,导出应用程序的当前堆快照。

      • -XX:HeapDumpPath:可以指定堆快照的保存位置。

    • 比如:-Xmx100m -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=D:\m.hprof

1.5.4 使用2:显示堆内存相关信息

  • jmap -heap pid
  • -jmap -histo pid

1.5.5 使用3:其它作用

  • jmap -permstat pid:查看系统的ClassLoader信息。
  • jmap -finalizerinfo:査看堆积在finalizer队列中的对象。

1.5.6 小结

  • 由于jmap将访问堆中的所有对象,为了保证在此过程中不被应用线程干扰,jmap需要借助安全点机制,让所有线程停留在不改变堆中数据的状态。也就是说,由jmap导出的堆快照必定是安全点位置的。这可能导致基于该堆快照的分析结果存在偏差。

  • 举个例子,假设在编译生成的机器码中,某些对象的生命周期在两个安全点之间,那么:live选项将无法探知到这些对象。

  • 另外,如果某个线程长时间无法跑到安全点,jmap将一直等下去。

  • 与前面讲的jstat则不同,垃圾回收器会主动将jstat所需要的摘要数据保存至固定位置之中,而jstat只需直接读取即可。

1.6 jhat:JDK自带堆分析工具

1.6.1 基本情况

  • jhat(JVM Heap Analysis Tool):Sun JDK提供的jhat命令与jmap命令搭配使用,用于分析jmap生成的heap dump文件(堆转储快照)。jhat内置了一个微型的HTTP/HTML服务器, 生成dump文件的分析结果后, 用户可以在浏览器中查看分析结果(分析虚拟机转储快照信息)。

  • 使用了jhat命令,就启动了一个http服务,端口是7000,即http://localhost:7000/,就可以在浏览器里分析。

  • 说明:jhat命令在JDK9、JDK10中已经被删除,官方建议用VisualVM代替。

1.6.2 基本语法

  • 它的基本使用语法为:jhat [option] [dumpfile],option参数如下:
    • -stack false|true:关闭 | 打开对象分配调用栈跟踪。
    • -refs false|true:关闭 | 打开对象引用跟踪。
    • -port port-number:设置jhat HTTP Server的端口号,默认7000。
    • -exclude exclude-file:执行对象查询时需要排除的数据成员列表文件。
    • -baseline exclude-file:指定一个基准堆转储。
    • -debug int:设置debug级别。
    • -version:启动后显示版本信息就退出。
    • -J<flag>:传入启动参数,比如-J -Xmx512m。

1.7 jstack:打印JVM中线程快照

  • 每当使用java命令执行一个带main方法的类时,就会启动JVM(应用程序),实际上就是在操作系统中启动一个JVM进程,JVM启动时,必然会创建以下5个线程:

    • main:主线程,执行我们指定的启动类的main方法。
      • 主线程,用于执行我们编写的java程序的main方法。
    • Reference Handler:处理引用的线程。
      • 它主要用于处理引用对象本身(软引用、弱引用、虚引用)的垃圾回收问题。
    • Finalizer:调用对象的finalize方法的线程,就是垃圾回收的线程。
      • JVM在垃圾收集时会将失去引用的对象包装成Finalizer对象(Reference的实现),并放入ReferenceQueue,由Finalizer线程来处理;最后将该Finalizer对象的引用置为null,由垃圾收集器来回收。
    • Attach Listener:负责接收外部的命令的线程。
      • 该线程是负责接收到外部的命令,执行该命令,并且把结果返回给发送者。通常我们会用一些命令去要求jvm给我们一些反馈信息,如:java -version、jmap、jstack等等。如果该线程在jvm启动的时候没有初始化,那么,则会在用户第一次执行jvm命令时,得到启动。
    • Signal Dispatcher:分发处理发送给JVM信号的线程。
      • 前面我们提到第一个Attach Listener线程的职责是接收外部jvm命令,当命令接收成功后,会交给signal dispather线程去进行分发到各个不同的模块处理命令,并且返回处理结果。signal dispather线程也是在第一次接收外部jvm命令时,进行初始化工作。
  • 编写java应用程序查看JVM启动时创建的所有线程,代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    public class JVMTest {
      public static void main(String[] args) throws Exception {
        ThreadMXBean threadMXBean = ManagementFactory.getThreadMXBean();
        ThreadInfo[] threadInfos = threadMXBean.dumpAllThreads(false, false);
        for(ThreadInfo threadInfo : threadInfos) {
          System.out.println(threadInfo.getThreadId() + "-" + threadInfo.getThreadName());
        }
      }
    }

    输出如下:
    5-Attach Listener
    4-Signal Dispatcher
    3-Finalizer
    2-Reference Handler
    1-main

1.7.1 基本情况

  • 生成线程快照的作用:可用于定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等问题。这些都是导致线程长时间停顿的常见原因。当线程出现停顿时,就可以用jstack显示各个线程调用的堆栈情况。

  • 官方帮助文档:https://docs.oracle.com/en/java/javase/11/tools/jstack.html

  • 在thread dump中,要留意下面几种状态

    • 死锁,Deadlock(重点关注)

    • 等待资源,Waiting on condition(重点关注)

    • 等待获取监视器,Waiting on monitor entry(重点关注)

    • 阻塞,Blocked(重点关注)

    • 执行中,Runnable

    • 暂停,Suspended

    • 对象等待中,Object.wait() 或 TIMED_WAITING

    • 停止,Parked

1.7.2 基本语法

  • 它的基本使用语法为:jstack option pid
  • jstack管理远程进程的话,需要在远程程序的启动参数中增加:
    • -Djava.rmi.server.hostname=…..
    • -Dcom.sun.management.jmxremote
    • -Dcom.sun.management.jmxremote.port=8888
    • -Dcom.sun.management.jmxremote.authenticate=false
    • -Dcom.sun.management.jmxremote.ssl=false
  • option参数:
    • -F:当正常输出的请求不被响应时,强制输出线程堆栈。
    • -l:除堆栈外,显示关于锁的附加信息。
    • -m:如果调用到本地方法的话,可以显示C/C++的堆栈。
    • -h:帮助操作。

1.8 jcmd:多功能命令行

1.8.1 基本情况

  • 在JDK 1.7以后,新增了一个命令行工具jcmd。

  • 它是一个多功能的工具,可以用来实现前面除了jstat之外所有命令的功能。比如:用它来导出堆、内存使用、查看Java进程、导出线程信息、执行GC、JVM运行时间等。

  • 官方帮助文档:https://docs.oracle.com/en/java/javase/11/tools/jcmd.html

  • jcmd拥有jmap的大部分功能,并且在Oracle的官方网站上也推荐使用jcmd命令代jmap命令。

1.8.2 基本语法

  • jcmd -l:列出所有的JVM进程。
  • jcmd pid help:针对指定的进程,列出支持的所有命令。
  • jcmd pid 具体命令:显示指定进程的指令命令的数据。

1.9 jstatd:远程主机信息收集

  • 之前的指令只涉及到监控本机的Java应用程序,而在这些工具中,一些监控工具也支持对远程计算机的监控(如jps、jstat)。为了启用远程监控,则需要配合使用jstatd 工具。

  • 命令jstatd是一个RMI服务端程序,它的作用相当于代理服务器,建立本地计算机与远程监控工具的通信。 jstatd服务器将本机的Java应用程序信息传递到远程计算机。

    image-20240303153523066

2、JVM监控及诊断工具-GUI

2.1 工具概述

  • 使用上一章命令行工具或组合能帮您获取目标Java应用性能相关的基础信息,但它们存在下列局限:

    • 无法获取方法级别的分析数据,如方法间的调用关系、各方法的调用次数和调用时间等(这对定位应用性能瓶颈至关重要)。
    • 要求用户登录到目标 Java 应用所在的宿主机上,使用起来不是很方便。
    • 分析数据通过终端输出,结果展示不够直观。
  • 为此,JDK提供了一些内存泄漏的分析工具,如jconsole,jvisualvm等,用于辅助开发人员定位问题,但是这些工具很多时候并不足以满足快速定位的需求。所以这里我们介绍的工具相对多一些、丰富一些。

  • 图形化综合诊断工具

    • JDK自带的工具
      • jconsole:JDK自带的可视化监控工具。查看Java应用程序的运行概况、监控堆信息、永久区(或元空间)使用情况、类加载情况等。位置:jdk\bin\jconsole.exe。
      • Visual VM:Visual VM是一个工具,它提供了一个可视界面,用于查看Java虚拟机上运行的基于Java技术的应用程序的详细信息。位置:jdk\bin\jvisualvm.exe。
      • JMC:Java Mission Control,内置Java Flight Recorder。能够以极低的性能开销收集Java虚拟机的性能数据。
    • 第三方工具
      • MAT:MAT(Memory Analyzer Tool)是基于Eclipse的内存分析工具,是一个快速、功能丰富的Java heap分析工具,它可以帮助我们查找内存泄漏和减少内存消耗。Eclipse的插件形式。
      • JProfiler:商业软件,需要付费。功能强大。与VisualVM类似。
      • Arthas:Alibaba开源的Java诊断工具。深受开发者喜爱。
      • Btrace:Java运行时追踪工具。可以在不停机的情况下,跟踪指定的方法调用、构造函数调用和系统内存等信息。

2.2 jConsole

2.2.1 基本概述

  • 启动:
    • jdk/bin目录下,启动jconsole.exe命令即可。
    • 不需要使用jps命令来查询。
  • 主要作用
    • 监控内存。
    • 监控线程。
    • 监控死锁。
    • 类加载与虚拟机信息。

2.2.2 三种连接方式

  • Local:使用JConsole连接一个正在本地系统运行的JVM,并且执行程序的和运行JConsole的需要是同一个用户。JConsole使用文件系统的授权通过RMI连接器连接到平台的MBean服务器上。这种从本地连接的监控能力只有Sun的JDK具有。
  • Remote:使用下面的URL通过RMI连接器连接到一个JMX代理,service:jmx:rmi:///jndi/rmi://hostName:portNum/jmxrmi。JConsole为建立连接,需要在环境变量中设置mx.remote.credentials来指定用户名和密码,从而进行授权。
  • Advanced:使用一个特殊的URL连接JMX代理。一般情况使用自己定制的连接器而不是RMI提供的连接器来连接JMX代理,或者是一个使用JDK1.4的实现了JMX和JMX Rmote的应用。

2.3 Visual VM

2.3.1 基本概述

  • Visual VM是一个功能强大的多合一故障诊断和性能监控的可视化工具。

  • 它集成了多个JDK命令行工具,使用Visual VM可用于显示虚拟机进程及进程的配置和环境信息(jps,jinfo),监视应用程序的CPU、GC、堆、方法区及线程的信息(jstat、jstack)等,甚至代替JConsole。

  • 在JDK 6 Update 7以后,Visual VM便作为JDK的一部分发布(VisualVM 在JDK/bin目录下),即:它完全免费。

  • 此外,Visual VM也可以作为独立的软件安装,首页:https://visualvm.github.io/index.html。

    image-20240303155016169
  • 主要功能:
    • 生成/读取堆内存快照。
    • 查看JVM参数和系统属性。
    • 查看运行中的虚拟机进程。
    • 生成/读取线程快照。
    • 程序资源的实时监控。
    • 其他功能
      • JMX代理连接。
      • 远程环境监控。
      • CPU分析和内存分析。

2.3.2 插件的安装

  • Visual VM的一大特点是支持插件扩展,并且插件安装非常方便。我们既可以通过离线下载插件文件*.nbm,然后在Plugin对话框的已下载页面下,添加已下载的插件。也可以在可用插件页面下,在线安装插件。(这里建议安装上:VisualGC)。插件地址:https://visualvm.github.io/pluginscenters.html。

    image-20240303155117834

2.3.3 连接方式

  • 本地连接:监控本地Java进程的CPU、类、线程等。
  • 远程连接:
    • 确定远程服务器的ip地址。
    • 添加JMX(通过JMX技术具体监控远端服务器哪个Java进程。
    • 修改bin/catalina.sh文件,连接远程的tomcat。
    • 在…/conf中添加jmxremote.access和jmxremote.password文件。
    • 将服务器地址改为公网ip地址。
    • 设置阿里云安全策略和防火墙策略。
    • 启动tomcat,查看tomcat启动日志和端口监听。
    • JMX中输入端口号、用户名、密码登录。

2.4 Arthas

2.4.1 基本概述

  • 前面,我们介绍了jdk自带的jvisualvm等免费工具,以及商业化工具Jprofiler。

    • jvisualvm界面

      image-20240303155522470

    • Jprofiler

      image-20240303155537539

  • 这两款工具在业界知名度也比较高,他们的优点是可以图形界面上看到各维度的性能数据,使用者根据这些数据进行综合分析,然后判断哪里出现了性能问题。

  • 但是这两款工具也有个缺点,都必须在服务端项目进程中配置相关的监控参数。然后工具通过远程连接到项目进程,获取相关的数据。这样就会带来一些不便,比如线上环境的网络是隔离的,本地的监控工具根本连不上线上环境。并且类似于Jprofiler这样的商业工具,是需要付费的。

  • 那么有没有一款工具不需要远程连接,也不需要配置监控参数,同时也提供了丰富的性能监控数据呢?今天跟大家介绍一款阿里巴巴开源的性能分析神器Arthas(阿尔萨斯)

  • Arthas(阿尔萨斯) 是Alibaba开源的Java诊断工具,深受开发者喜爱。在线排查问题,无需重启;动态跟踪Java代码;实时监控JVM状态。

  • Arthas 支持JDK 6+,支持Linux/Mac/Windows,采用命令行交互模式,同时提供丰富的 Tab 自动补全功能,进一步方便进行问题的定位和诊断。

  • 当你遇到以下类似问题而束手无策时,Arthas可以帮助你解决:

    • 这个类从哪个 jar 包加载的?为什么会报各种类相关的 Exception?
    • 我改的代码为什么没有执行到?难道是我没 commit?分支搞错了?
    • 遇到问题无法在线上 debug,难道只能通过加日志再重新发布吗?
    • 线上遇到某个用户的数据处理有问题,但线上同样无法 debug,线下无法重现!
    • 是否有一个全局视角来查看系统的运行状况?
    • 有什么办法可以监控到JVM的实时运行状态?
    • 怎么快速定位应用的热点,生成火焰图?
  • Arthas是基于这些工具开发而来:

    • greys-anatomy: Arthas代码基于Greys二次开发而来,非常感谢Greys之前所有的工作,以及Greys原作者对Arthas提出的意见和建议!
    • termd: Arthas的命令行实现基于termd开发,是一款优秀的命令行程序开发框架,感谢termd提供了优秀的框架。

    • crash: Arthas的文本渲染功能基于crash中的文本渲染功能开发,可以从这里看到源码,感谢crash在这方面所做的优秀工作。

    • cli: Arthas的命令行界面基于vert.x提供的cli库进行开发,感谢vert.x在这方面做的优秀工作。

    • compiler Arthas里的内存编绎器代码来源。

    • Apache Commons Net Arthas里的Telnet Client代码来源。

    • JavaAgent:运行在 main方法之前的拦截器,它内定的方法名叫 premain ,也就是说先执行 premain 方法然后再执行 main 方法。

    • ASM:一个通用的Java字节码操作和分析框架。它可以用于修改现有的类或直接以二进制形式动态生成类。ASM提供了一些常见的字节码转换和分析算法,可以从它们构建定制的复杂转换和代码分析工具。ASM提供了与其他Java字节码框架类似的功能,但是主要关注性能。因为它被设计和实现得尽可能小和快,所以非常适合在动态系统中使用(当然也可以以静态方式使用,例如在编译器中)。

  • 官方使用文档:https://arthas.aliyun.com/zh-cn/。

2.4.2 安装与使用

安装

卸载

  • 在 Linux/Unix/Mac 平台删除下面文件:

    • rm -rf ~/.arthas/
    • rm -rf ~/logs/arthas
  • Windows平台直接删除user home下面的.arthas和logs/arthas目录。

工程目录

  • arthas-agent:基于JavaAgent技术的代理

  • bin:一些启动脚本

  • arthas-boot:Java版本的一键安装启动脚本

  • arthas-client:telnet client代码

  • arthas-common:一些共用的工具类和枚举类

  • arthas-core:核心库,各种arthas命令的交互和实现

  • arthas-demo:示例代码

  • arthas-memorycompiler:内存编绎器代码,Fork from https://github.com/skalogs/SkaETL/tree/master/compiler

  • arthas-packaging:maven打包相关的

  • arthas-site:arthas站点

  • arthas-spy:编织到目标类中的各个切面

  • static:静态资源

  • arthas-testcase:测试

启动

  • Arthas 只是一个 java 程序,所以可以直接用 java -jar 运行。

  • 执行成功后,arthas提供了一种命令行方式的交互方式,arthas会检测当前服务器上的Java进程,并将进程列表展示出来,用户输入对应的编号(1、2、3、4…)进行选择,然后回车。

    • 方式1:java -jar arthas-boot.jar

      1
      2
      3
      4
      5
      6
      7
      # 选择进程(输入[]内编号(不是PID)回车)
      [INFO] arthas-boot version: 3.1.4
      [INFO] Found existing java process, please choose one and hit RETURN.
      * [1]: 11616 com.Arthas
        [2]: 8676
        [3]: 16200 org.jetbrains.jps.cmdline.Launcher
        [4]: 21032 org.jetbrains.idea.maven.server.RemoteMavenServer
    • 方式2:运行时选择 Java 进程 PID:java -jar arthas-boot.jar [PID]

查看进程

  • 查看 PID 的方式可以通过 ps 命令,也可以通过 JDK 提供的 jps命令。
    • 查看运行的 java 进程信息
      • jps -mlvV
      • ps -ef| grep java
    • 筛选 java 进程信息
      • jps -mlvV | grep [xxx]

查看日志

  • cat ~/logs/arthas/arthas.log

参看帮助

  • java -jar arthas-boot.jar -h

web console

  • 除了在命令行查看外,Arthas 目前还支持 Web Console。在成功启动连接进程之后就已经自动启动,可以直接访问 http://127.0.0.1:8563/ 访问,页面上的操作模式和控制台完全一样。

    image-20240303160908617

退出

  • 最后一行 [arthas@7457]$,说明打开进入了监控客户端,在这里就可以执行相关命令进行查看了。
    • 使用quit\exit:退出当前客户端。
    • 使用stop\shutdown:关闭arthas服务端,并退出所有客户端。

2.4.3 相关诊断指令

基础指令

image-20240303161101088

jvm相关

  • dashboard命令:可以查看当前系统的实时数据面板。

    • https://arthas.aliyun.com/doc/dashboard。

    • 展示当前tomcat的多线程状态、JVM各区域、GC情况等信息。

    • 输入 Q 或者 Ctrl+C 可以退出dashboard命令。

    • 常用参数:

      • -i1000:每次执行间隔时间,这是单位是毫秒。
      • -n4:执行多少次dashboard,不指定的话会一直刷新。

    image-20240303161158625

    • 可以看到,这里会显示出线程(按照cpu占用百分比倒排)、内存(堆空间实时情况)、GC情况等数据。
  • thread命令:查看当前 JVM 的线程堆栈信息。

    • 常用参数:

      • 无 :显示所有线程的状态信息。
      • -b:显示当前处于BLOCKED状态的线程,可以排查线程锁的问题。
      • -i 5000:查看在接下来的多长时间内统计cpu利用率,单位毫秒。
      • -n 5:查看cpu占用率前5的线程的堆栈信息。
      • 直接跟着线程id,可以看到指定thread的堆栈信息。
    • Arthas支持管道,可以用thread 1 | grep 'main('查找到main class。

      1
      2
      3
      4
      [arthas@49290]$ thread 1 | grep 'main('
      at org.apache.zookeeper.server.ZooKeeperServerMain.main(ZooKeeperServerMain.java:55)
      at org.apache.zookeeper.server.quorum.QuorumPeerMain.main(QuorumPeerMain.java:81)
      [arthas@49290]$ 
  • jvm命令:查看jvm详细的性能数据。

    image-20240303161443127
  • 其它。

class/classloader相关

  • sc命令:查看 JVM 已加载的类信息。

    • https://arthas.aliyun.com/doc/sc

    • 常用参数:

      • class-pattern 类名表达式匹配。
      • -d:输出当前类的详细信息,包括这个类所加载的原始文件来源、类的声明、加载的ClassLoader等详细信息。如果一个类被多个ClassLoader所加载,则会出现多次。
      • -E:开启正则表达式匹配,默认为通配符匹配。
      • -f:输出当前类的成员变量信息(需要配合参数-d一起使用)
      • -x:指定输出静态变量时属性的遍历深度,默认为 0,即直接使用 toString 输出。
    • 补充:

      • class-pattern支持全限定名,如com.test.AAA,也支持com/test/AAA这样的格式,这样,我们从异常堆栈里面把类名拷贝过来的时候,不需要在手动把/替换为.了。
      • sc默认开启了子类匹配功能,也就是说所有当前类的子类也会被搜索出来,想要精确的匹配,请打开options disable-sub-class true开关。
    1
    sc -d com.atguigu.arthas.OOMTest
  • sm命令:查看已加载类的方法信息。

    • https://arthas.aliyun.com/doc/sm

    • sm 命令只能看到由当前类所声明 (declaring) 的方法,父类则无法看到。

    • 常用参数:

      • class-pattern:类名表达式匹配。
      • method-pattern:方法名表达式匹配。
      • -d:展示每个方法的详细信息。
      • -E:开启正则表达式匹配,默认为通配符匹配。
    1
    sm -d com.atguigu.arthas.OOMTest main
  • jad命令:反编译指定已加载类的源码。

    • 在 Arthas Console 上,反编译出来的源码是带语法高亮的,阅读更方便。

    • 当然,反编译出来的 java 代码可能会存在语法错误,但不影响你进行阅读理解。

    • 编译java.lang.String。

    image-20240303162216405
  • mc命令:Memory Compiler/内存编译器,编译.java文件生成.class。

    image-20240303162302586

  • redefine命令:加载外部的.class文件,redefine jvm已加载的类。

    image-20240303162335217

  • classloader命令:查看 classloader 的继承树,urls,类加载信息。

    • 了解当前系统中有多少类加载器,以及每个加载器加载的类数量,帮助您判断是否有类加载器泄漏。
    • 常用参数:
      • -t : 查看ClassLoader的继承树。
      • -l : 按类加载实例查看统计信息。
      • -c : 用classloader对应的hashcode 来查看对应的jar urls。

    image-20240303162452290

monitor/watch/trace相关

  • monitor命令:方法执行监控。

    • 对匹配 class-pattern/method-pattern的类、方法的调用进行监控。涉及方法的调用次数、执行时间、失败率等。
    • https://arthas.aliyun.com/doc/monitor。

    • monitor 命令是一个非实时返回命令。

    • 常用参数:

      • class-pattern:类名表达式匹配。
      • method-pattern:方法名表达式匹配。
      • -c:统计周期,默认值为120秒。

    image-20240303162707510

  • watch命令:方法执行数据观测。

    • 让你能方便的观察到指定方法的调用情况。能观察到的范围为:返回值、抛出异常、入参,通过编写 groovy 表达式进行对应变量的查看。
    • 常用参数:
      • class-pattern:类名表达式匹配。
      • method-pattern:方法名表达式匹配。
      • express:观察表达式。
      • condition-express:条件表达式。
      • -b:在方法调用之前观察(默认关闭)。
      • -e:在方法异常之后观察(默认关闭)。
      • -s:在方法返回之后观察(默认关闭)。
      • -f:在方法结束之后(正常返回和异常返回)观察 (默认开启)。
      • -x:指定输出结果的属性遍历深度,默认为0。
    • 这里重点要说明的是观察表达式,观察表达式的构成主要由 ognl 表达式组成,所以你可以这样写"{params,returnObj}",只要是一个合法的 ognl 表达式,都能被正常支持。
    • 举例:watch 全限定类名 方法名 returnObj
  • trace命令:方法内部调用路径,并输出方法路径上的每个节点上耗时。

    • https://arthas.aliyun.com/doc/trace。

    • 补充说明:

      • trace 命令能主动搜索 class-pattern/method-pattern 对应的方法调用路径,渲染和统计整个调用链路上的所有性能开销和追踪调用链路。

      • trace 能方便的帮助你定位和发现因 RT 高而导致的性能问题缺陷,但其每次只能跟踪一级方法的调用链路

      • trace 在执行的过程中本身是会有一定的性能开销,在统计的报告中并未像 JProfiler 一样预先减去其自身的统计开销。所以这统计出来有些许的不准,渲染路径上调用的类、方法越多,性能偏差越大。但还是能让你看清一些事情的。

    • 参数说明:

      image-20240303163309555

  • stack命令:输出当前方法被调用的调用路径。

  • tt命令:方法执行数据的时空隧道,记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测。

    • TimeTunnel的缩写。

    • 参数说明:

      • -t:表明希望记录下类 *Test 的 print 方法的每次执行情况。
      • -n 3:指定你需要记录的次数,当达到记录次数时 Arthas 会主动中断tt命令的记录过程,避免人工操作无法停止的情况。
      • -s:筛选指定方法的调用信息。
      • -i:参数后边跟着对应的 INDEX 编号查看到它的详细信息。
      • -p:重做一次调用 通过 –replay-times 指定 调用次数,通过 –replay-interval 指定多次调用间隔(单位ms, 默认1000ms)。
    • 举例:

      image-20240303163735221

      • 表格中的字段说明:

        image-20240303163752317

其它

  • 使用>将结果重写到日志文件,使用&指令命令是后台运行,session断开不影响任务执行(生命周期默认为1天)。

    • jobs:列出所有job。
    • kill:强制终止任务。
    • fg:将暂停的任务拉到前台执行。
    • bg:将暂停的任务放到后台执行。
    • grep:搜索满足条件的结果。
    • plaintext:将命令的结果去除ANSI颜色。
    • wc:按行统计输出结果。
    • options:查看或设置Arthas全局开关。
    • profiler:使用async-profiler对应用采样,生成火焰图。
  • profiler命令:支持生成应用热点的火焰图。

    • 使用:

      • 启动profiler:profiler start
      • 获取已采集的sample的数量:profiler getSamples

      • 查看profiler状态:profiler status

      • 停止profiler,生成svg格式结果:profiler stop

      • 默认情况下,生成的结果保存到应用的工作目录下的arthas-output目录。可以通过 –file参数来指定输出结果路径。比如:profiler stop –file /tmp/output.svg/。
      • 生成html格式结果:profiler stop –format html

      • 通过浏览器查看arthas-output下面的profiler结果。默认情况下,arthas使用3658端口,则可以打开: http://localhost:3658/arthas-output/ 查看到arthas-output目录下面的profiler结果:

        image-20240303164114974

      • 点击可以查看具体的结果:

        image-20240303164203765

  • options命令:全局开关。可以获取或设置。

    image-20240303164258245

2.5 eclipse MAT

2.5.1 基本概述

  • MAT(Memory Analyzer Tool)工具是一款功能强大的Java堆内存分析器。可以用于查找内存泄漏以及查看内存消耗情况。

  • MAT是基于Eclipse开发的,不仅可以单独使用,还可以作为插件的形式嵌入在Eclipse中使用。是一款免费的性能分析工具,使用起来非常方便。大家可以在https://www.eclipse.org/mat/downloads.php下载并使用MAT。

    image-20240317124224579

  • 只要确保机器上装有JDK并配置好相关的环境变量,MAT可正常启动。还可以在Eclipse中以插件的方式安装:

    image-20240317124237797

2.5.2 获取堆dump文件

2.5.2.1 dump文件内容

  • MAT可以分析heap dump文件。在进行内存分析时,只要获得了反映当前设备内存映像的hprof文件,通过MAT打开就可以直观地看到当前的内存信息。

  • 一般说来,这些内存信息包含:

    • 所有的对象信息,包括对象实例、成员变量、存储于栈中的基本类型值和存储于堆中的其他对象的引用值。

    • 所有的类信息,包括classloader、类名称、父类、静态变量等。

    • GCRoot到所有的这些对象的引用路径。

    • 线程信息,包括线程的调用栈及此线程的线程局部变量(TLS)。

2.5.2.2 两点说明

  • 说明1,缺点:MAT 不是一个万能工具,它并不能处理所有类型的堆存储文件。但是比较主流的厂家和格式,例如 Sun, HP, SAP 所采用的 HPROF 二进制堆存储文件,以及 IBM 的 PHD 堆存储文件等都能被很好的解析。

  • 说明2:最吸引人的还是能够快速为开发人员生成内存泄漏报表,方便定位问题和分析问题。虽然MAT有如此强大的功能,但是内存分析也没有简单到一键完成的程度,很多内存问题还是需要我们从MAT展现给我们的信息当中通过经验和直觉来判断才能发现。、

    image-20240317124413837

2.5.2.3 获取dump文件

  • 方法一:通过前一章介绍的 jmap工具生成,可以生成任意一个java进程的dump文件;

  • 方法二:通过配置JVM参数生成。

    • 选项”-XX:+HeapDumpOnOutOfMemoryError” 或 “-XX:+HeapDumpBeforeFullGC”。
    • 选项”-XX:HeapDumpPath”所代表的含义就是当程序出现OutofMemory时,将会在相应的目录下生成一份dump文件。如果不指定选项“-XX:HeapDumpPath”则在当前目录下生成dump文件。

对比:考虑到生产环境中几乎不可能在线对其进行分析,大都是采用离线分析,因此使用jmap+MAT工具是最常见的组合。

  • 方法三:使用VisualVM可以导出堆dump文件。

  • 方法四:使用MAT既可以打开一个已有的堆快照,也可以通过MAT直接从活动Java程序中导出堆快照。该功能将借助jps列出当前正在运行的 Java 进程,以供选择并获取快照。

    image-20240317124555288

2.5.3 分析堆dump文件

image-20240317124826964

image-20240317124838334

image-20240317124846210

2.5.3.1 histogram

  • 展示了各个类的实例数目以及这些实例的Shallow heap 或Retainedheap的总和。

  • MAT 的直方图和jmap的-histo子命令一样,都能够展示各个类的实例数目以及这些实例的 Shallow heap 总和。但是,MAT 的直方图还能够计算 Retained heap,并支持基于实例数目或 Retained heap 的排序方式(默认为 Shallow heap)。

  • 此外,MAT 还可以将直方图中的类按照超类、类加载器或者包名分组。

  • 当选中某个类时,MAT 界面左上角的 Inspector 窗口将展示该类的 Class 实例的相关信息,如类加载器等。

2.5.3.2 thread overview

  • 查看系统中的Java线程。
  • 查看局部变量的信息。

2.5.3.3 获得对象相互引用的关系

  • with outgoing references
  • with incoming references

2.5.3.4 浅堆与深堆

  • shallow heap:

    • 浅堆(Shallow Heap)是指一个对象所消耗的内存。在32位系统中,一个对象引用会占据 4个字节,一个int类型会占据4个字节,long型变量会占据8个字节,每个对象头需要占用8 个字节。根据堆快照格式不同,对象的大小可能会向8字节进行对齐。

    • 以String为例:2个int值共占8字节,对象引用占用4字节,对象头8字节,合计20字节,向8字节对 齐,故占24字节。(jdk7中)

      image-20240317124924860

    • 这24字节为String对象的浅堆大小。它与String的value实际取值无关,无论字符串长度如何,浅堆大小始终是24字节。

  • retained heap:

    • 保留集(Retained Set):对象A的保留集指当对象A被垃圾回收后,可以被释放的所有的对象集合(包括对象A本身), 即对象A的保留集可以被认为是只能通过对象A被直接或间接访问到的所有对象的集合。通俗地说,就是指仅被对象A所持有的对象的集合。
    • 深堆(Retained Heap):深堆是指对象的保留集中所有的对象的浅堆大小之和。
    • 注意:浅堆指对象本身占用的内存,不包括其内部引用对象的大小。一个对象的深堆指只能通过该对象访问到的(直接或间接)所有对象的浅堆之和,即对象被回收后,可以释放的真实空间。
  • 补充:对象实际大小

    • 另外一个常用的概念是对象的实际大小。这里,对象的实际大小定义为一个对象所能触及的所有对象的浅堆大小之和,也就是通常意义上我们说的对象大小。与深堆相比,似乎这个在日常开发中更为直观和被人接受,但实际上,这个概念和垃圾回收无关。

    • 下图显示了一个简单的对象引用关系图,对象A引用了C和D,对象B引用了C和E。那么对象A的浅堆大小只是A本身,不含C和D,而A的实际大小为A、C、D三者之和。而A的深堆大小为A与D之和,由于对象C还可以通过对象B访问到,因此不在对象A的深堆范围内。

      image-20240317125117588

  • 练习:

    image-20240317125136950

    • 上图中,GC Roots直接引用了A和B两个对象。

      • A对象的Retained Size=A对象的Shallow Size。
      • B对象的Retained Size=B对象的Shallow Size + C对象的Shallow Size。
      • 这里不包括D对象,因为D对象被GC Roots直接引用。
    • 如果GC Roots不引用D对象呢?

      image-20240317125226332

      • 此时,B对象的Retained Size=B对象的Shallow Size + C对象的Shallow Size + D对象Shallow Size。
  • 案例分析:StudentTrace

    • 考虑Lily同学:15 个 webpage,每个对应152个字节 15 * 152 = 2280字节 –>即为elementData的实际大小。
    • 关心的是elementData的深堆1288是如何计算出来的?能被7整除,且能被3整除,以及能被7整除,且能被5整除的数值有:0,21,42,63,84,35,70 共7个数。
      • 7 * 152 = 1064字节
      • 2280 - 1064 + 72 = 1288字节!
    • 这72个字节是什么?
      • 15个elementData的元素 * 4字节 = 60字节
      • 60 + 8个对象头的字节数 + 4字节 = 72字节

2.5.3.5 支配树

  • 支配树(Dominator Tree):支配树的概念源自图论。

  • MAT提供了一个称为支配树(Dominator Tree)的对象图。支配树体现了对象实例间的支配关系。在对象引用图中,所有指向对象B的路径都经过对象A,则认为对象A支配对象B。如果对象A是离对象B最近的一个支配对象,则认为对象A为对象B的直接支配者。支配树是基于对象间的引用图所建立的,它有以下基本性质:

    • 对象A的子树(所有被对象A支配的对象集合)表示对象A的保留集(retained set),即深堆。

    • 如果对象A支配对象B,那么对象A的直接支配者也支配对象B。

    • 支配树的边与对象引用图的边不直接对应。

  • 如下图所示:左图表示对象引用图,右图表示左图所对应的支配树。对象A和B由根对象直接支配,由于在到对象C的路径中,可以经过A,也可以经过B,因此对象C的直接支配者也是根对象。对象F与对象D相互引用,因为到对象F的所有路径必然经过对象D,因此,对象D是对象F的直接支配者。而到对象D的所有路径中,必然经过对象C,即使是从对象F到对象D的引用,从根节点出发,也是经过对象C的,所以,对象D的直接支配者为对象C。

    image-20240317125631926

  • 同理,对象E支配对象G。到达对象H的可以通过对象D,也可以通过对象E,因此对象D和E都不能支配对象H,而经过对象C既可以到达D也可以到达E,因此对象C为对象H的直接支配者。

  • 在MAT中,单击工具栏上的对象支配树按钮,可以打开对象支配树视图。

    image-20240317125650267

  • 下图显示了对象支配树视图的一部分。该截图显示部分Lily学生的history队列的直接支配对象。即当Lily对象被回收,也会一并回收的所有对象。显然能被3或者5整除的网页不会出现在该列表中,因为它们同时被另外两名学生对象引用。

    image-20240317125701772

2.5.4 案例:Tomcat堆溢出分析

  • Tomcat是最常用的Java Servlet容器之一,同时也可以当做单独的Web服务器使用。Tomcat本身使用Java实现,并运行于Java虚拟机之上。在大规模请求时,Tomcat有可能会因为无法承受压力而发生内存溢出错误。这里根据一个被压垮的Tomcat的堆快照文件,来分析Tomcat在崩溃时的内部情况。

    image-20240317125800089

    image-20240317125807104

    • sessions对象,它占用了约17MB空间:

      image-20240317125829050

    • 可以看到sessions对象为ConcurrentHashMap,其内部分为16个Segment。从深堆大小看,每个Segment都比较平均,大约为1MB,合计17MB。

      image-20240317125840415

      image-20240317125851349

    • 当前堆中含有9941个session,并且每一个session的深堆为1592字节,合计约15MB,达到当前堆大小的50%。

      image-20240317125905516

      image-20240317125915243

      image-20240317125922454

      • 根据当前的session总数,可以计算每秒的平均压力为:9941/(1403324677648-1403324645728)*1000=311次/秒。
      • 由此推断,在发生Tomcat堆溢出时,Tomcat在连续30秒的时间内,平均每秒接收了约311次不同客户端的请求,创建了合计9941个session。

2.6 补充1:再谈内存泄漏

2.6.1 案例1

  • 代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    import java.util.Arrays;
    import java.util.EmptyStackException;

    public class Stack {

    private Object[] elements;
    private int size = 0;
    private static final int DEFAULT_INITIAL_CAPACITY = 16;

    public Stack() {
    elements = new Object[DEFAULT_INITIAL_CAPACITY];
    }

    public void push(Object e) {
    ensureCapacity();
    elements[size++] = e;
    }

    public Object pop() {
    if (size == 0) {
    throw new EmptyStackException();
    }
    return elements[--size];
    }

    private void ensureCapacity() {
    if (elements.length == size) {
    elements = Arrays.copyOf(elements, 2 * size + 1);
    }
    }
    }
  • 上述程序并没有明显的错误,但是这段程序有一个内存泄漏,随着GC活动的增加,或者内存占用的不断增加,程序性能的降低就会表现出来,严重时可导致内存泄漏,但是这种失败情况相对较少。代码的主要问题在pop函数,下面通过这张图示展现,假设这个栈一直增长,增长后如下图所示:

    image-20240309121404578

  • 当进行大量的pop操作时,由于引用未进行置空,gc是不会释放的,如下图所示:

    image-20240309121515378

  • 从上图中看以看出,如果栈先增长,在收缩,那么从栈中弹出的对象将不会被当作垃圾回收,即使程序不再使用栈中的这些队象,他们也不会回收,因为栈中仍然保存这对象的引用,俗称过期引用,这个内存泄露很隐蔽。

  • 解决方法:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    // 一旦引用过期,清空这些引用,将引用置空。
    public Object pop() {
    if (size == 0) {
    throw new EmptyStackException();
    }
    Object result = elements[--size];
    elements[size] = null;
    return result;
    }

    image-20240309122020032

2.6.2 案例2

  • 代码如下:

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    public class TestActivity extends Activity {

    private static final Object key = new Object();

    @Override
    protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    setContentView(R.layout.activity_main);
    //匿名线程
    new Thread() {
    public void run() {
    synchronized (key) {
    try {
    key.wait();
    } catch (InterruptedException e) {
    e.printStackTrace();
    }
    }
    }
    }.start();
    }
    }

    image-20240309122233612
    image-20240309122254254

  • 解决方法:

    • 使用线程时,一定要确保线程在周期性对象(如Activity)销毁时能正常结束,如能正常结束,但是Activity销毁后还需执行一段时间,也可能造成泄露,此时可采用WeakReference方法来解决,另外在使用Handler的时候,如存在Delay操作,也可以采用WeakReference;
    • 使用Handler + HandlerThread时,记住在周期性对象销毁时调用looper.quit()方法。

2.7 补充2:支持使用OQL语言查询对象信息

  • MAT支持一种类似于SQL的查询语言OQL(Object Query Language)。OQL使用类SQL语法,可以在堆中进行对象的查找和筛选。

2.7.1 SELECT子句

  • 在MAT中,Select子句的格式与SQL基本一致,用于指定要显示的列。Select子句中可以使用“*”,查看结果对象的引用实例(相当于outgoing references)。
    • SELECT * FROM java.util.Vector v
  • 使用“OBJECTS”关键字,可以将返回结果集中的项以对象的形式显示。
    • SELECT objects v.elementData FROM java.util.Vector v
    • SELECT OBJECTS s.value FROM java.lang.String s
  • 在Select子句中,使用“AS RETAINED SET”关键字可以得到所得对象的保留集。
    • SELECT AS RETAINED SET * FROM com.atguigu.mat.Student
  • “DISTINCT”关键字用于在结果集中去除重复对象。
    • SELECT DISTINCT OBJECTS classof(s) FROM java.lang.String s

2.7.2 FROM子句

  • 下例使用正则表达式,限定搜索范围,输出所有com包下所有类的实例:

    • SELECT * FROM "com.*"
  • 也可以直接使用类的地址进行搜索。使用类的地址的好处是可以区分被不同ClassLoader加载的同一种类型。

    • select * from 0x37a0b4d

2.7.3 WHERE子句

  • Where子句用于指定OQL的查询条件。OQL查询将只返回满足Where子句指定条件的对象。Where子句的格式与传统SQL极为相似。下例返回长度大于10的char数组。

    • SELECT * FROM char[] s WHERE s.@length>10
  • 下例返回包含“java”子字符串的所有字符串,使用“LIKE”操作符,“LIKE”操作符的操作参数为正则表达式。

    • SELECT * FROM java.lang.String s WHERE toString(s) LIKE ".*java.*"
  • 下例返回所有value域不为null的字符串,使用“=”操作符。

    • SELECT * FROM java.lang.String s where s.value!=null
  • Where子句支持多个条件的AND、OR运算。下例返回数组长度大于15,并且深堆大于1000字节的所有Vector对象。

    • SELECT * FROM java.util.Vector v WHERE v.elementData.@length>15 AN D v.@retainedHeapSize>1000

2.7.4 内置对象与方法

  • OQL中可以访问堆内对象的属性,也可以访问堆内代理对象的属性。访问堆内对象的属性时,格式如下:[ <alias>. ] <field> . <field>. <field>,其中alias为对象名称。
  • 访问java.io.File对象的path属性,并进一步访问path的value属性:SELECT toString(f.path.value) FROM java.io.File f
  • 下例显示了String对象的内容、objectid和objectAddress。
    • SELECT s.toString(), s.@objectId, s.@objectAddress FROM java.lang.String s
  • 下例显示java.util.Vector内部数组的长度。
    • SELECT v.elementData.@length FROM java.util.Vector v
  • 下例显示了所有的java.util.Vector对象及其子类型。
    • select * from INSTANCEOF java.util.Vector

2.8 JProfiler

2.8.1 基本概述

  • 在运行Java的时候有时候想测试运行时占用内存情况,这时候就需要使用测试工具查看了。在eclipse里面有 Eclipse Memory Analyzer tool(MAT)插件可以测试,而在IDEA中也有这么一个插件,就是JProfiler。
  • JProfiler 是由 ej-technologies 公司开发的一款 Java 应用性能诊断工具。功能强大,但是收费。
  • 官网下载地址:https://www.ej-technologies.com/products/jprofiler/overview.html。
  • 特点:
    • 使用方便 、界面操作友好 (简单且强大)。
    • 对被分析的应用影响小 (提供模板)。
    • CPU,Thread,Memory分析功能尤其强大。
    • 支持对jdbc,noSql, jsp, servlet, socket等进行分析。
    • 支持多种模式(离线,在线)的分析。
    • 支持监控本地、远程的JVM。
    • 跨平台,拥有多种操作系统的安装版本。
  • 主要功能:
    • 方法调用:对方法调用的分析可以帮助您了解应用程序正在做什么,并找到提高其性能的方法。
    • 内存分配:通过分析堆上对象、引用链和垃圾收集能帮您修复内存泄漏问题,优化内存使用。
    • 线程和锁:JProfiler提供多种针对线程和锁的分析视图助您发现多线程问题。
    • 高级子系统:许多性能问题都发生在更高的语义级别上。例如,对于JDBC调用,您可能希望找出执行最慢的 SQL语句。JProfiler支持对这些子系统进行集成分析。

2.8.2 具体使用

2.8.2.1 数据采集方式

  • JProfier数据采集方式分为两种:Sampling(样本采集)和Instrumentation(重构模式)

    • Instrumentation: 这是JProfiler全功能模式。在class加载之前,JProfier把相关功能代码写入到需要分析的class的bytecode中,对正在运行的jvm有一定影响。

      • 优点: 功能强大。在此设置中,调用堆栈信息是准确的。
      • 缺点:若要分析的class较多,则对应用的性能影响较大,CPU开销可能很高(取决于Filter的控制)。因此使用此模式一般配合Filter使用,只对特定的类或包进行分析。
    • Sampling: 类似于样本统计, 每隔一定时间(5ms)将每个线程栈中方法栈中的信息统计出来。

      • 优点:对CPU的开销非常低,对应用影响小(即使你不配置任何Filter)
      • 缺点:一些数据/特性不能提供(例如:方法的调用次数、执行时间)
  • 注: JProfiler本身没有指出数据的采集类型,这里的采集类型是针对方法调用的采集类型。因为JProfiler的绝大多数核心功能都依赖方法调用采集的数据, 所以可以直接认为是JProfiler的数据采集类型。

2.8.2.2 遥感监测Telemetries

  • 遥感监测Telemetries 查看JVM的运行信息)
    • 整体视图 Overview:显示堆内存、cpu、线程以及GC等活动视图。
    • 内存 Memory:显示一张关于内存变化的活动时间表。
    • 记录的对象 Recorded objects:显示一张关于活动对象与数组的图表的活动时间表。
    • 记录吞吐量 Record Throughput:显示一段时间累计的JVM生产和释放的活动时间表。
    • 垃圾回收活动 GC Activity:显示一张关于垃圾回收活动的活动时间表。
    • 类 Classes:显示一个与已装载类的图表的活动时间表。
    • 线程 Threads:显示一个与动态线程图表的活动时间表。
    • CPU负载 CPU Load:显示一段时间中CPU的负载图表。

2.8.2.3 内存视图Live Memory

  • Live memory 内存剖析:class/class instance的相关信息。 例如对象的个数,大小,对象创建的方法执行栈,对象创建的热点。

    • 所有对象All Objects:显示所有加载的类的列表和在堆上分配的实例数。只有Java 1.5 (JVMTI)才会显示此视图。

      image-20240317143438686

    • 记录对象 Record Objects:查看特定时间段对象的分配,并记录分配的调用堆栈。

    • 分配访问树 Allocation Call Tree:显示一棵请求树或者方法、类、包或对已选择类有带注释的分配信息的J2EE组件。

    • 分配热点 Allocation Hot Spots:显示一个列表,包括方法、类、包或分配已选类的J2EE组件。你可以标注当前值并且显示差异值。对于每个热点都可以显示它的跟踪记录树。

    • 类追踪器 Class Tracker:类跟踪视图可以包含任意数量的图表,显示选定的类和包的实例与时间。

  • 分析:内存中的对象的情况

    • 频繁创建的Java对象:死循环、循环次数过多。
    • 存在大的对象:读取文件时,byte[]应该边读边写。–>如果长时间不写出的话,导致byte[]过大。
    • 存在内存泄漏。

2.8.2.4 堆遍历heap walker

  • Heap walker 堆遍历 :对一定时间内收集的内存对像信息进行静态分析,功能强大且使用。包含对象的outgoing reference, incoming reference, biggest object等。

    • Classes:显示所有类和它们的实例,可以右击具体的类”Used Selected Instance”实现进一步跟踪。
    • 分配 Allocations:为所有记录对象显示分配树和分配热点。
    • 索引 References:为单个对象和“显示到垃圾回收根目录的路径”提供索引图的显示功能。还能提供合并输入视图和输出视图的功能。
    • 时间 Time:显示一个对已记录对象的解决时间的柱状图。
    • 检查 Inspections:显示了一个数量的操作,将分析当前对象集在某种条件下的子集,实质是一个筛选的过程。
    • 图表 Graph:你需要在references视图和biggest视图手动添加对象到图表,它可以显示对象的传入和传出引用,能方便的找到垃圾收集器根源。
  • Ps:在工具栏点击”Go To Start”可以使堆内存重新计数,也就是回到初始状态。

2.8.2.5 cpu视图cpu views

  • JProfiler 提供不同的方法来记录访问树以优化性能和细节。线程或者线程组以及线程状况可以被所有的视图选择。所有的视图都可以聚集到方法、类、包或J2EE组件等不同层上。
    • 访问树 Call Tree:显示一个积累的自顶向下的树,树中包含所有在JVM中已记录的访问队列。JDBC,JMS和JNDI服务请求都被注释在请求树中。请求树可以根据Servlet和JSP对URL的不同需要进行拆分。
    • 热点 Hot Spots:显示消耗时间最多的方法的列表。对每个热点都能够显示回溯树。该热点可以按照方法请求,JDBC,JMS和JNDI服务请求以及按照URL请求来进行计算。
    • 访问图 Call Graph:显示一个从已选方法、类、包或J2EE组件开始的访问队列的图。
    • 方法统计 Method Statistis:显示一段时间内记录的方法的调用时间细节。

2.8.2.6 线程视图threads

  • JProfiler通过对线程历史的监控判断其运行状态,并监控是否有线程阻塞产生,还能将一个线程所管理的方法以树状形式呈现。对线程剖析。

    • 线程历史 Thread History:显示一个与线程活动和线程状态在一起的活动时间表。
    • 线程监控 Thread Monitor:显示一个列表,包括所有的活动线程以及它们目前的活动状况。
    • 线程转储 Thread Dumps:显示所有线程的堆栈跟踪。
  • 线程分析主要关心三个方面:

    • web容器的线程最大数。比如:Tomcat的线程容量应该略大于最大并发数。
    • 线程阻塞。
    • 线程死锁。

2.8.2.7 监视器 & 锁Monitors & locks

  • 监控和锁 Monitors & Locks 所有线程持有锁的情况以及锁的信息。观察JVM的内部线程并查看状态:

    • 死锁探测图表 Current Locking Graph :显示JVM中的当前死锁图表。

    • 目前使用的监测器 Current Monitors :显示目前使用的监测器并且包括它们的关联线程。

    • 锁定历史图表 Locking History Graph :显示记录在JVM中的锁定历史。

    • 历史检测记录 Monitor History :显示重大的等待事件和阻塞事件的历史记录。

    • 监控器使用统计 Monitor Usage Statistics :显示分组监测,线程和监测类的统计监测数据。

2.9 Java Mission Control

2.9.1 基本概述

  • 在 Oracle 收购 Sun 之前,Oracle 的 JRockit 虚拟机提供了一款叫做 JRockit Mission Control 的虚拟机诊断工具。

  • 在Oracle收购Sun之后,Oracle公司同时拥有了Sun Hotspot和JRockit两款虚拟机。根据Oracle对于Java的战略,在今后的发展中,会将JRockit的优秀特性移植到Hotspot上。其中,一个重要的改进就是在Sun的JDK中加入了JRockit的支持。

  • 在Oracle JDK 7u40之后,Mission Control这款工具已经绑定在Oracle JDK中发布。

  • 自 Java 11 开始,本节介绍的 JFR 已经开源。但在之前的 Java 版本,JFR 属于 Commercial Feature,需要通过 Java 虚拟机参数-XX:+UnlockCommercialFeatures开启。

  • 如果你有兴趣请可以查看OpenJDK的Mission Control项目。https://github.com/JDKMissionControl/jmc。

  • Mission Control 位于%JAVA_HOME%/ bin/jmc.exe,打开这款软件。

    image-20240317144237040

    image-20240317144243489

  • Java Mission Control(简称 JMC),Java官方提供的性能强劲的工具。是一个用于对 Java 应用程序进行管理、监视、概要分析和故障排除的工具套件。

  • 它包含一个 GUI 客户端,以及众多用来收集 Java 虚拟机性能数据的插件,如 JMX Console(能够访问用来存放虚拟机各个子系统运行数据的MXBeans),以及虚拟机内置的高效 profiling 工具 Java Flight Recorder(JFR)。

  • JMC 的另一个优点就是:采用取样,而不是传统的代码植入技术,对应用性能的影响非常非常小,完全可以开着 JMC 来做压测(唯一影响可能是 full gc 多了)。

  • 功能:实时监控 JVM 运行时的状态。

    • 如果是远程服务器,使用前要开 JMX。

      • -Dcom.sun.management.jmxremote.port=${YOUR PORT}
      • -Dcom.sun.management.jmxremote
      • -Dcom.sun.management.jmxremote.authenticate=false
      • -Dcom.sun.management.jmxremote.ssl=false
      • -Djava.rmi.server.hostname=${YOUR HOST/IP}
    • 文件 -> 连接 -> 创建新连接, 填入上面 JMX 参数的 host 和 port。

      image-20240317144411215

  • Mission Control的界面非常有特色,在默认的界面中,以飞机仪表的视图显示了Java堆使用率、CPU使用率和Live Set+Fragmentation。

  • Mission Control的一大特点是可以自由设置图标内容。比如,如果希望在飞机仪表面板再增加一个监控项,可以单击右侧的添加按钮“+”,按需添加各种统计图表。

    • “触发器” tab 可以根据 CPU、线程等信息,设定一定的阈值,来触发报警。

    • “内存” tab 提供 heap 和 GC 的信息。可以关注 GC次数、时间以及随着 GC 发生 heap 的内存变化情况,以此来调整 jvm 参数。

    • “线程” tab 可以关注每条线程所占的CPU、死锁情况以及线程堆栈信息。

2.9.2 Java Flight Recorder

  • Java Flight Recorder 是 JMC 的其中一个组件。
  • Java Flight Recorder能够以极低的性能开销收集 Java 虚拟机的性能数据。
  • JFR 的性能开销很小,在默认配置下平均低于 1%。与其他工具相比,JFR 能够直接访问虚拟机内的数据,并且不会影响虚拟机的优化。因此,它非常适用于生产环境下满负荷运行的 Java 程序。
  • Java Flight Recorder和JDK Mission Control共同创建了一个完整的工具链。JDK Mission Control可对Java Flight Recorder连续收集低水平和详细的运行时信息进行高效,详细的分析。

2.9.2.1 事件类型

  • 当启用时,JFR 将记录运行过程中发生的一系列事件。其中包括 Java 层面的事件,如线程事件、锁事件,以及 Java 虚拟机内部的事件,如新建对象、垃圾回收和即时编译事件。
  • 按照发生时机以及持续时间来划分,JFR 的事件共有四种类型,它们分别为以下四种。
    • 瞬时事件(Instant Event),用户关心的是它们发生与否,例如异常、线程启动事件。
    • 持续事件(Duration Event),用户关心的是它们的持续时间,例如垃圾回收事件。
    • 计时事件(Timed Event),是时长超出指定阈值的持续事件。
    • 取样事件(Sample Event),是周期性取样的事件。
  • 取样事件的其中一个常见例子便是方法抽样(Method Sampling),即每隔一段时间统计各个线程的栈轨迹。如果在这些抽样取得的栈轨迹中存在一个反复出现的方法,那么我们可以推测该方法是热点方法。

2.9.2.2 启动方式

  • 方式1:使用-XX:StartFlightRecording=参数。

    • 比如:下面命令中,JFR 将会在 Java 虚拟机启动 5s 后(对应delay=5s)收集数据,持续 20s(对应duration=20s)。当收集完毕后,JFR 会将收集得到的数据保存至指定的文件中(对应filename=myrecording.jfr)
      • java -XX:StartFlightRecording=delay=5s,duration=20s,filename=myrecording.jfr,settings=profile MyApp
    • 由于 JFR 将持续收集数据,如果不加以限制,那么 JFR 可能会填满硬盘的所有空间。因此,我们有必要对这种模式下所收集的数据进行限制。比如:
      • java -XX:StartFlightRecording=maxage=10m,maxsize=100m,name=SomeLabel MyApp
  • 方式2:使用jcmd的JFR.*子命令。

    • 通过jcmd来让 JFR 开始收集数据、停止收集数据,或者保存所收集的数据,对应的子命令分别为JFR.start,JFR.stop,以及JFR.dump。
      • $ jcmd <PID> JFR.start settings=profile maxage=10m maxsize=150m name=SomeLabel
    • 上述命令运行过后,目标进程中的 JFR 已经开始收集数据。此时,我们可以通过下述命令来导出已经收集到的数据:
      • $ jcmd <PID> JFR.dump name=SomeLabel filename=myrecording.jfr
    • 最后,我们可以通过下述命令关闭目标进程中的 JFR:
      • $ jcmd <PID> JFR.stop name=SomeLabel
  • 方式3:JMC 的 JFR 插件。

    image-20240317144835423

2.9.2.3 Java Flight Recorder取样分析

  • 要采用取样,必须先添加参数,否则会报错:

    image-20240317144914746

    • -XX:+UnlockCommercialFeatures
    • -XX:+FlightRecorder
  • 取样时间默认 1 分钟,可自行按需调整,事件设置选为 profiling,然后可以设置取样 profile 哪些信息,比如:

    • 加上对象数量的统计:Java Virtual Machine -> GC -> Detailed -> Object Count/Object Count after GC。

    • 方法调用采样的间隔从 10ms 改为 1ms(但不能低于 1ms,否则会影响性能了): Java Virtual Machine -> Profiling -> Method Profiling Sample/Method Sampling Information。

    • Socket 与 File 采样, 10ms 太久,但即使改为 1ms 也未必能抓住什么,可以干脆取消掉: Java Application->File Read/FileWrite/Socket Read/Socket Write。

    image-20240317144954657

    • 然后就开始 Profile,到时间后 Profile 结束,会自动把记录下载回来,在 JMC 中展示。

      image-20240317145013624

    • 从展示信息中,我们大致可以读到内存和CPU信息、代码、线程和IO等比较重要的信息展示。

  • 它可以显示系统中的热点方法和占用的时间,下图显示了占用CPU时间最多的方法调用树信息。

    image-20240317145118030

  • 在IO页面,还可以看到磁盘文件的读写情况,以及网络Socket的访问情况。下图显示了在记录时间段内,程序通过Socket访问的远程主机以及数据读取次数和数据读取数量。

    image-20240317145149971

3、JVM运行时参数

3.1 JVM参数选项类型

3.1.1 类型一:标准参数选项

  • 特点:

    • 比较稳定,后续版本基本不会变化。
    • 以-开头。
  • 各种选项:运行java或者java -help可以看到所有的标准选项。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    选项包括:
        -d32          使用 32 位数据模型 (如果可用)
        -d64          使用 64 位数据模型 (如果可用)
        -server       选择 "server" VM
                      默认 VM 是 server.
     
        -cp <目录和 zip/jar 文件的类搜索路径>
        -classpath <目录和 zip/jar 文件的类搜索路径>
                      用 ; 分隔的目录, JAR 档案
                      和 ZIP 档案列表, 用于搜索类文件。
        -D<名称>=<值>
                      设置系统属性
        -verbose:[class|gc|jni]
                      启用详细输出
        -version      输出产品版本并退出
        -version:<值>
                      警告: 此功能已过时, 将在
                      未来发行版中删除。
                      需要指定的版本才能运行
        -showversion  输出产品版本并继续
        -jre-restrict-search | -no-jre-restrict-search
                      警告: 此功能已过时, 将在
                      未来发行版中删除。
                      在版本搜索中包括/排除用户专用 JRE
        -? -help      输出此帮助消息
        -X            输出非标准选项的帮助
        -ea[:<packagename>...|:<classname>]
        -enableassertions[:<packagename>...|:<classname>]
                      按指定的粒度启用断言
        -da[:<packagename>...|:<classname>]
        -disableassertions[:<packagename>...|:<classname>]
                      禁用具有指定粒度的断言
        -esa | -enablesystemassertions
                      启用系统断言
        -dsa | -disablesystemassertions
                      禁用系统断言
        -agentlib:<libname>[=<选项>]
                      加载本机代理库 <libname>, 例如 -agentlib:hprof
                      另请参阅 -agentlib:jdwp=help 和 -agentlib:hprof=help
        -agentpath:<pathname>[=<选项>]
                      按完整路径名加载本机代理库
        -javaagent:<jarpath>[=<选项>]
                      加载 Java 编程语言代理, 请参阅 java.lang.instrument
        -splash:<imagepath>
                      使用指定的图像显示启动屏幕
    有关详细信息, 请参阅 http://www.oracle.com/technetwork/java/javase/documentation/index.html。
  • 补充内容:-server 与 -client

    • Hotspot JVM有两种模式,分别是server和client,分别通过-server和-client模式设置
      • 在32位Windows系统上,默认使用Client类型的JVM。要想使用Server模式,则机器配置至少有2个以上的CPU和2G以上的物理内存。 client模式适用于对内存要求较小的桌面应用程序,默认使用Serial串行垃圾收集器。
      • 64位机器上只支持server模式的JVM,适用于需要大内存的应用程序,默认使用并行垃圾收集器。
    • 关于server和client的官网介绍为:https://docs.oracle.com/javase/8/docs/technotes/guides/vm/server-class.html

3.1.2 类型二:-X参数选项

  • 特点:

    • 非标准化参数。
    • 功能还是比较稳定的。但官方说后续版本可能会变更。
    • 以-X开头。
  • 各种选项:运行java -X命令可以看到所有的X选项。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    -Xmixed           混合模式执行 (默认)
    -Xint             仅解释模式执行
    -Xcomp            仅采用即时编译器模式
    -Xbootclasspath:<用 ; 分隔的目录和 zip/jar 文件>
                          设置搜索路径以引导类和资源
    -Xbootclasspath/a:<用 ; 分隔的目录和 zip/jar 文件>
                          附加在引导类路径末尾
    -Xbootclasspath/p:<用 ; 分隔的目录和 zip/jar 文件>
                          置于引导类路径之前
    -Xdiag            显示附加诊断消息
    -Xnoclassgc       禁用类垃圾收集
    -Xincgc           启用增量垃圾收集
    -Xloggc:<file>    将 GC 状态记录在文件中 (带时间戳)
    -Xbatch           禁用后台编译
    -Xms<size>        设置初始 Java 堆大小
    -Xmx<size>        设置最大 Java 堆大小
    -Xss<size>        设置 Java 线程堆栈大小
    -Xprof            输出 cpu 配置文件数据
    -Xfuture          启用最严格的检查, 预期将来的默认值
    -Xrs              减少 Java/VM 对操作系统信号的使用 (请参阅文档)
    -Xcheck:jni       对 JNI 函数执行其他检查
    -Xshare:off       不尝试使用共享类数据
    -Xshare:auto      在可能的情况下使用共享类数据 (默认)
    -Xshare:on        要求使用共享类数据, 否则将失败。
    -XshowSettings    显示所有设置并继续
    -XshowSettings:all     显示所有设置并继续
    -XshowSettings:vm   显示所有与 vm 相关的设置并继续
    -XshowSettings:properties    显示所有属性设置并继续
    -XshowSettings:locale    显示所有与区域设置相关的设置并继续
     
    -X 选项是非标准选项, 如有更改, 恕不另行通知。
  • JVM的JIT编译模式相关的选项:

    • -Xint:禁用JIT,所有字节码都被解释执行,这个模式的速度最慢的。
    • -Xcomp:所有字节码第一次使用就都被编译成本地代码,然后再执行。
    • -Xmixed:混合模式,默认模式,让JIT根据程序运行的情况,有选择地将某些代码编译成本地代码。
  • 特别地:

    • -Xms<size>:设置初始 Java 堆大小,等价于-XX:InitialHeapSize。
    • -Xmx<size>:设置最大 Java 堆大小,等价于-XX:MaxHeapSize。
    • -Xss<size>:设置 Java 线程堆栈大小,-XX:ThreadStackSize。

3.1.3 类型三:-XX参数选项

分类

  • Boolean类型格式:

    • -XX:+<option>:表示启用 option 属性。
    • -XX:-<option>:表示禁用 option 属性。
    • 举例:
      • -XX:-UseParallelGC:不选择垃圾收集器为并行收集器。
      • -XX:+UseG1GC:表示启用G1收集器。
      • -XX:+UseAdaptiveSizePolicy:自动选择年轻代区大小和相应的Survivor区比例。
    • 说明:因为有的指令默认是开启的,所以可以使用-关闭。
  • 非Boolean类型格式(key-value类型):

    • 子类型1:数值型格式-XX:<option>=<number>。number表示数值,number可以带上单位,比如:’m’ 、’M’ 表示兆, ‘k’ 、’K’ 表示Kb, ‘g’ 、 ‘G’ 表示 g(例如 32k跟32768是一样的效果),例如:
      • -XX:NewSize=1024m:表示设置新生代初始大小为1024兆。
      • -XX:MaxGCPauseMillis=500:表示设置GC停顿时间:500毫秒。
      • -XX:GCTimeRatio=19:表示设置吞吐量。
      • -XX:NewRatio=2:表示新生代与老年代的比例。
    • 子类型2:非数值型格式-XX:<name>=<string>。例如:
      • -XX:HeapDumpPath=/usr/local/heapdump.hprof:用来指定heap转存文件的存储路径。
  • 特别地:

    • -XX:+PrintFlagsFinal
      • 输出所有参数的名称和默认值。
      • 默认不包括Diagnostic和Experimental的参数。
      • 可以配合-XX:+UnlockDiagnosticVMOptions-XX:UnlockExperimentalVMOptions使用。
  • 各种参数默认值(参考):

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    142
    143
    144
    145
    146
    147
    148
    149
    150
    151
    152
    153
    154
    155
    156
    157
    158
    159
    160
    161
    162
    163
    164
    165
    166
    167
    168
    169
    170
    171
    172
    173
    174
    175
    176
    177
    178
    179
    180
    181
    182
    183
    184
    185
    186
    187
    188
    189
    190
    191
    192
    193
    194
    195
    196
    197
    198
    199
    200
    201
    202
    203
    204
    205
    206
    207
    208
    209
    210
    211
    212
    213
    214
    215
    216
    217
    218
    219
    220
    221
    222
    223
    224
    225
    226
    227
    228
    229
    230
    231
    232
    233
    234
    235
    236
    237
    238
    239
    240
    241
    242
    243
    244
    245
    246
    247
    248
    249
    250
    251
    252
    253
    254
    255
    256
    257
    258
    259
    260
    261
    262
    263
    264
    265
    266
    267
    268
    269
    270
    271
    272
    273
    274
    275
    276
    277
    278
    279
    280
    281
    282
    283
    284
    285
    286
    287
    288
    289
    290
    291
    292
    293
    294
    295
    296
    297
    298
    299
    300
    301
    302
    303
    304
    305
    306
    307
    308
    309
    310
    311
    312
    313
    314
    315
    316
    317
    318
    319
    320
    321
    322
    323
    324
    325
    326
    327
    328
    329
    330
    331
    332
    333
    334
    335
    336
    337
    338
    339
    340
    341
    342
    343
    344
    345
    346
    347
    348
    349
    350
    351
    352
    353
    354
    355
    356
    357
    358
    359
    360
    361
    362
    363
    364
    365
    366
    367
    368
    369
    370
    371
    372
    373
    374
    375
    376
    377
    378
    379
    380
    381
    382
    383
    384
    385
    386
    387
    388
    389
    390
    391
    392
    393
    394
    395
    396
    397
    398
    399
    400
    401
    402
    403
    404
    405
    406
    407
    408
    409
    410
    411
    412
    413
    414
    415
    416
    417
    418
    419
    420
    421
    422
    423
    424
    425
    426
    427
    428
    429
    430
    431
    432
    433
    434
    435
    436
    437
    438
    439
    440
    441
    442
    443
    444
    445
    446
    447
    448
    449
    450
    451
    452
    453
    454
    455
    456
    457
    458
    459
    460
    461
    462
    463
    464
    465
    466
    467
    468
    469
    470
    471
    472
    473
    474
    475
    476
    477
    478
    479
    480
    481
    482
    483
    484
    485
    486
    487
    488
    489
    490
    491
    492
    493
    494
    495
    496
    497
    498
    499
    500
    501
    502
    503
    504
    505
    506
    507
    508
    509
    510
    511
    512
    513
    514
    515
    516
    517
    518
    519
    520
    521
    522
    523
    524
    525
    526
    527
    528
    529
    530
    531
    532
    533
    534
    535
    536
    537
    538
    539
    540
    541
    542
    543
    544
    545
    546
    547
    548
    549
    550
    551
    552
    553
    554
    555
    556
    557
    558
    559
    560
    561
    562
    563
    564
    565
    566
    567
    568
    569
    570
    571
    572
    573
    574
    575
    576
    577
    578
    579
    580
    581
    582
    583
    584
    585
    586
    587
    588
    589
    590
    591
    592
    593
    594
    595
    596
    597
    598
    599
    600
    601
    602
    603
    604
    605
    606
    607
    608
    609
    610
    611
    612
    613
    614
    615
    616
    617
    618
    619
    620
    621
    622
    623
    624
    625
    626
    627
    628
    629
    630
    631
    632
    633
    634
    635
    636
    637
    638
    639
    640
    641
    642
    643
    644
    645
    646
    647
    648
    649
    650
    651
    652
    653
    654
    655
    656
    657
    658
    659
    660
    661
    662
    663
    664
    665
    666
    667
    668
    669
    670
    671
    672
    673
    674
    675
    676
    677
    678
    679
    680
    681
    682
    683
    684
    685
    686
    687
    688
    689
    690
    691
    692
    693
    694
    695
    696
    697
    698
    699
    700
    701
    702
    703
    704
    705
    706
    707
    708
    709
    710
    711
    712
    713
    714
    715
    716
    717
    718
    719
    720
    721
    722
    723
    724
    725
    726
    727
    728
    729
    730
    731
    732
    733
    734
    735
    [Global flags]
         intx ActiveProcessorCount                      = -1                                  {product}
        uintx AdaptiveSizeDecrementScaleFactor          = 4                                   {product}
        uintx AdaptiveSizeMajorGCDecayTimeScale         = 10                                  {product}
        uintx AdaptiveSizePausePolicy                   = 0                                   {product}
        uintx AdaptiveSizePolicyCollectionCostMargin    = 50                                  {product}
        uintx AdaptiveSizePolicyInitializingSteps       = 20                                  {product}
        uintx AdaptiveSizePolicyOutputInterval          = 0                                   {product}
        uintx AdaptiveSizePolicyWeight                  = 10                                  {product}
        uintx AdaptiveSizeThroughPutPolicy              = 0                                   {product}
        uintx AdaptiveTimeWeight                        = 25                                  {product}
         bool AdjustConcurrency                         = false                               {product}
         bool AggressiveHeap                            = false                               {product}
         bool AggressiveOpts                            = false                               {product}
         intx AliasLevel                                = 3                                   {C2 product}
         bool AlignVector                               = true                                {C2 product}
         intx AllocateInstancePrefetchLines             = 1                                   {product}
         intx AllocatePrefetchDistance                  = 256                                 {product}
         intx AllocatePrefetchInstr                     = 3                                   {product}
         intx AllocatePrefetchLines                     = 3                                   {product}
         intx AllocatePrefetchStepSize                  = 64                                  {product}
         intx AllocatePrefetchStyle                     = 1                                   {product}
         bool AllowJNIEnvProxy                          = false                               {product}
         bool AllowNonVirtualCalls                      = false                               {product}
         bool AllowParallelDefineClass                  = false                               {product}
         bool AllowUserSignalHandlers                   = false                               {product}
         bool AlwaysActAsServerClassMachine             = false                               {product}
         bool AlwaysCompileLoopMethods                  = false                               {product}
         bool AlwaysLockClassLoader                     = false                               {product}
         bool AlwaysPreTouch                            = false                               {product}
         bool AlwaysRestoreFPU                          = false                               {product}
         bool AlwaysTenure                              = false                               {product}
         bool AssertOnSuspendWaitFailure                = false                               {product}
         bool AssumeMP                                  = false                               {product}
         intx AutoBoxCacheMax                           = 128                                 {C2 product}
        uintx AutoGCSelectPauseMillis                   = 5000                                {product}
         intx BCEATraceLevel                            = 0                                   {product}
         intx BackEdgeThreshold                         = 100000                              {pd product}
         bool BackgroundCompilation                     = true                                {pd product}
        uintx BaseFootPrintEstimate                     = 268435456                           {product}
         intx BiasedLockingBulkRebiasThreshold          = 20                                  {product}
         intx BiasedLockingBulkRevokeThreshold          = 40                                  {product}
         intx BiasedLockingDecayTime                    = 25000                               {product}
         intx BiasedLockingStartupDelay                 = 4000                                {product}
         bool BindGCTaskThreadsToCPUs                   = false                               {product}
         bool BlockLayoutByFrequency                    = true                                {C2 product}
         intx BlockLayoutMinDiamondPercentage           = 20                                  {C2 product}
         bool BlockLayoutRotateLoops                    = true                                {C2 product}
         bool BranchOnRegister                          = false                               {C2 product}
         bool BytecodeVerificationLocal                 = false                               {product}
         bool BytecodeVerificationRemote                = true                                {product}
         bool C1OptimizeVirtualCallProfiling            = true                                {C1 product}
         bool C1ProfileBranches                         = true                                {C1 product}
         bool C1ProfileCalls                            = true                                {C1 product}
         bool C1ProfileCheckcasts                       = true                                {C1 product}
         bool C1ProfileInlinedCalls                     = true                                {C1 product}
         bool C1ProfileVirtualCalls                     = true                                {C1 product}
         bool C1UpdateMethodData                        = true                                {C1 product}
         intx CICompilerCount                          := 12                                  {product}
         bool CICompilerCountPerCPU                     = true                                {product}
         bool CITime                                    = false                               {product}
         bool CMSAbortSemantics                         = false                               {product}
        uintx CMSAbortablePrecleanMinWorkPerIteration   = 100                                 {product}
         intx CMSAbortablePrecleanWaitMillis            = 100                                 {manageable}
        uintx CMSBitMapYieldQuantum                     = 10485760                            {product}
        uintx CMSBootstrapOccupancy                     = 50                                  {product}
         bool CMSClassUnloadingEnabled                  = true                                {product}
        uintx CMSClassUnloadingMaxInterval              = 0                                   {product}
         bool CMSCleanOnEnter                           = true                                {product}
         bool CMSCompactWhenClearAllSoftRefs            = true                                {product}
        uintx CMSConcMarkMultiple                       = 32                                  {product}
         bool CMSConcurrentMTEnabled                    = true                                {product}
        uintx CMSCoordinatorYieldSleepCount             = 10                                  {product}
         bool CMSDumpAtPromotionFailure                 = false                               {product}
         bool CMSEdenChunksRecordAlways                 = true                                {product}
        uintx CMSExpAvgFactor                           = 50                                  {product}
         bool CMSExtrapolateSweep                       = false                               {product}
        uintx CMSFullGCsBeforeCompaction                = 0                                   {product}
        uintx CMSIncrementalDutyCycle                   = 10                                  {product}
        uintx CMSIncrementalDutyCycleMin                = 0                                   {product}
         bool CMSIncrementalMode                        = false                               {product}
        uintx CMSIncrementalOffset                      = 0                                   {product}
         bool CMSIncrementalPacing                      = true                                {product}
        uintx CMSIncrementalSafetyFactor                = 10                                  {product}
        uintx CMSIndexedFreeListReplenish               = 4                                   {product}
         intx CMSInitiatingOccupancyFraction            = -1                                  {product}
        uintx CMSIsTooFullPercentage                    = 98                                  {product}
       double CMSLargeCoalSurplusPercent                = 0.950000                            {product}
       double CMSLargeSplitSurplusPercent               = 1.000000                            {product}
         bool CMSLoopWarn                               = false                               {product}
        uintx CMSMaxAbortablePrecleanLoops              = 0                                   {product}
         intx CMSMaxAbortablePrecleanTime               = 5000                                {product}
        uintx CMSOldPLABMax                             = 1024                                {product}
        uintx CMSOldPLABMin                             = 16                                  {product}
        uintx CMSOldPLABNumRefills                      = 4                                   {product}
        uintx CMSOldPLABReactivityFactor                = 2                                   {product}
         bool CMSOldPLABResizeQuicker                   = false                               {product}
        uintx CMSOldPLABToleranceFactor                 = 4                                   {product}
         bool CMSPLABRecordAlways                       = true                                {product}
        uintx CMSParPromoteBlocksToClaim                = 16                                  {product}
         bool CMSParallelInitialMarkEnabled             = true                                {product}
         bool CMSParallelRemarkEnabled                  = true                                {product}
         bool CMSParallelSurvivorRemarkEnabled          = true                                {product}
        uintx CMSPrecleanDenominator                    = 3                                   {product}
        uintx CMSPrecleanIter                           = 3                                   {product}
        uintx CMSPrecleanNumerator                      = 2                                   {product}
         bool CMSPrecleanRefLists1                      = true                                {product}
         bool CMSPrecleanRefLists2                      = false                               {product}
         bool CMSPrecleanSurvivors1                     = false                               {product}
         bool CMSPrecleanSurvivors2                     = true                                {product}
        uintx CMSPrecleanThreshold                      = 1000                                {product}
         bool CMSPrecleaningEnabled                     = true                                {product}
         bool CMSPrintChunksInDump                      = false                               {product}
         bool CMSPrintEdenSurvivorChunks                = false                               {product}
         bool CMSPrintObjectsInDump                     = false                               {product}
        uintx CMSRemarkVerifyVariant                    = 1                                   {product}
         bool CMSReplenishIntermediate                  = true                                {product}
        uintx CMSRescanMultiple                         = 32                                  {product}
        uintx CMSSamplingGrain                          = 16384                               {product}
         bool CMSScavengeBeforeRemark                   = false                               {product}
        uintx CMSScheduleRemarkEdenPenetration          = 50                                  {product}
        uintx CMSScheduleRemarkEdenSizeThreshold        = 2097152                             {product}
        uintx CMSScheduleRemarkSamplingRatio            = 5                                   {product}
       double CMSSmallCoalSurplusPercent                = 1.050000                            {product}
       double CMSSmallSplitSurplusPercent               = 1.100000                            {product}
         bool CMSSplitIndexedFreeListBlocks             = true                                {product}
         intx CMSTriggerInterval                        = -1                                  {manageable}
        uintx CMSTriggerRatio                           = 80                                  {product}
         intx CMSWaitDuration                           = 2000                                {manageable}
        uintx CMSWorkQueueDrainThreshold                = 10                                  {product}
         bool CMSYield                                  = true                                {product}
        uintx CMSYieldSleepCount                        = 0                                   {product}
        uintx CMSYoungGenPerWorker                      = 67108864                            {pd product}
        uintx CMS_FLSPadding                            = 1                                   {product}
        uintx CMS_FLSWeight                             = 75                                  {product}
        uintx CMS_SweepPadding                          = 1                                   {product}
        uintx CMS_SweepTimerThresholdMillis             = 10                                  {product}
        uintx CMS_SweepWeight                           = 75                                  {product}
         bool CheckEndorsedAndExtDirs                   = false                               {product}
         bool CheckJNICalls                             = false                               {product}
         bool ClassUnloading                            = true                                {product}
         bool ClassUnloadingWithConcurrentMark          = true                                {product}
         intx ClearFPUAtPark                            = 0                                   {product}
         bool ClipInlining                              = true                                {product}
        uintx CodeCacheExpansionSize                    = 65536                               {pd product}
        uintx CodeCacheMinimumFreeSpace                 = 512000                              {product}
         bool CollectGen0First                          = false                               {product}
         bool CompactFields                             = true                                {product}
         intx CompilationPolicyChoice                   = 3                                   {product}
    ccstrlist CompileCommand                            =                                     {product}
        ccstr CompileCommandFile                        =                                     {product}
    ccstrlist CompileOnly                               =                                     {product}
         intx CompileThreshold                          = 10000                               {pd product}
         bool CompilerThreadHintNoPreempt               = true                                {product}
         intx CompilerThreadPriority                    = -1                                  {product}
         intx CompilerThreadStackSize                   = 0                                   {pd product}
        uintx CompressedClassSpaceSize                  = 1073741824                          {product}
        uintx ConcGCThreads                             = 0                                   {product}
         intx ConditionalMoveLimit                      = 3                                   {C2 pd product}
         intx ContendedPaddingWidth                     = 128                                 {product}
         bool ConvertSleepToYield                       = true                                {pd product}
         bool ConvertYieldToSleep                       = false                               {product}
         bool CrashOnOutOfMemoryError                   = false                               {product}
         bool CreateMinidumpOnCrash                     = false                               {product}
         bool CriticalJNINatives                        = true                                {product}
         bool DTraceAllocProbes                         = false                               {product}
         bool DTraceMethodProbes                        = false                               {product}
         bool DTraceMonitorProbes                       = false                               {product}
         bool Debugging                                 = false                               {product}
        uintx DefaultMaxRAMFraction                     = 4                                   {product}
         intx DefaultThreadPriority                     = -1                                  {product}
         intx DeferPollingPageLoopCount                 = -1                                  {product}
         intx DeferThrSuspendLoopCount                  = 4000                                {product}
         bool DeoptimizeRandom                          = false                               {product}
         bool DisableAttachMechanism                    = false                               {product}
         bool DisableExplicitGC                         = false                               {product}
         bool DisplayVMOutputToStderr                   = false                               {product}
         bool DisplayVMOutputToStdout                   = false                               {product}
         bool DoEscapeAnalysis                          = true                                {C2 product}
         bool DontCompileHugeMethods                    = true                                {product}
         bool DontYieldALot                             = false                               {pd product}
        ccstr DumpLoadedClassList                       =                                     {product}
         bool DumpReplayDataOnError                     = true                                {product}
         bool DumpSharedSpaces                          = false                               {product}
         bool EagerXrunInit                             = false                               {product}
         intx EliminateAllocationArraySizeLimit         = 64                                  {C2 product}
         bool EliminateAllocations                      = true                                {C2 product}
         bool EliminateAutoBox                          = true                                {C2 product}
         bool EliminateLocks                            = true                                {C2 product}
         bool EliminateNestedLocks                      = true                                {C2 product}
         intx EmitSync                                  = 0                                   {product}
         bool EnableContended                           = true                                {product}
         bool EnableResourceManagementTLABCache         = true                                {product}
         bool EnableSharedLookupCache                   = true                                {product}
         bool EnableTracing                             = false                               {product}
        uintx ErgoHeapSizeLimit                         = 0                                   {product}
        ccstr ErrorFile                                 =                                     {product}
        ccstr ErrorReportServer                         =                                     {product}
       double EscapeAnalysisTimeout                     = 20.000000                           {C2 product}
         bool EstimateArgEscape                         = true                                {product}
         bool ExitOnOutOfMemoryError                    = false                               {product}
         bool ExplicitGCInvokesConcurrent               = false                               {product}
         bool ExplicitGCInvokesConcurrentAndUnloadsClasses  = false                               {product}
         bool ExtendedDTraceProbes                      = false                               {product}
        ccstr ExtraSharedClassListFile                  =                                     {product}
         bool FLSAlwaysCoalesceLarge                    = false                               {product}
        uintx FLSCoalescePolicy                         = 2                                   {product}
       double FLSLargestBlockCoalesceProximity          = 0.990000                            {product}
         bool FailOverToOldVerifier                     = true                                {product}
         bool FastTLABRefill                            = true                                {product}
         intx FenceInstruction                          = 0                                   {ARCH product}
         intx FieldsAllocationStyle                     = 1                                   {product}
         bool FilterSpuriousWakeups                     = true                                {product}
        ccstr FlightRecorderOptions                     =                                     {product}
         bool ForceNUMA                                 = false                               {product}
         bool ForceTimeHighResolution                   = false                               {product}
         intx FreqInlineSize                            = 325                                 {pd product}
       double G1ConcMarkStepDurationMillis              = 10.000000                           {product}
        uintx G1ConcRSHotCardLimit                      = 4                                   {product}
        uintx G1ConcRSLogCacheSize                      = 10                                  {product}
         intx G1ConcRefinementGreenZone                 = 0                                   {product}
         intx G1ConcRefinementRedZone                   = 0                                   {product}
         intx G1ConcRefinementServiceIntervalMillis     = 300                                 {product}
        uintx G1ConcRefinementThreads                   = 0                                   {product}
         intx G1ConcRefinementThresholdStep             = 0                                   {product}
         intx G1ConcRefinementYellowZone                = 0                                   {product}
        uintx G1ConfidencePercent                       = 50                                  {product}
        uintx G1HeapRegionSize                          = 0                                   {product}
        uintx G1HeapWastePercent                        = 5                                   {product}
        uintx G1MixedGCCountTarget                      = 8                                   {product}
         intx G1RSetRegionEntries                       = 0                                   {product}
        uintx G1RSetScanBlockSize                       = 64                                  {product}
         intx G1RSetSparseRegionEntries                 = 0                                   {product}
         intx G1RSetUpdatingPauseTimePercent            = 10                                  {product}
         intx G1RefProcDrainInterval                    = 10                                  {product}
        uintx G1ReservePercent                          = 10                                  {product}
        uintx G1SATBBufferEnqueueingThresholdPercent    = 60                                  {product}
         intx G1SATBBufferSize                          = 1024                                {product}
         intx G1UpdateBufferSize                        = 256                                 {product}
         bool G1UseAdaptiveConcRefinement               = true                                {product}
        uintx GCDrainStackTargetSize                    = 64                                  {product}
        uintx GCHeapFreeLimit                           = 2                                   {product}
        uintx GCLockerEdenExpansionPercent              = 5                                   {product}
         bool GCLockerInvokesConcurrent                 = false                               {product}
        uintx GCLogFileSize                             = 8192                                {product}
        uintx GCPauseIntervalMillis                     = 0                                   {product}
        uintx GCTaskTimeStampEntries                    = 200                                 {product}
        uintx GCTimeLimit                               = 98                                  {product}
        uintx GCTimeRatio                               = 99                                  {product}
        uintx HeapBaseMinAddress                        = 2147483648                          {pd product}
         bool HeapDumpAfterFullGC                       = false                               {manageable}
         bool HeapDumpBeforeFullGC                      = false                               {manageable}
         bool HeapDumpOnOutOfMemoryError                = false                               {manageable}
        ccstr HeapDumpPath                              =                                     {manageable}
        uintx HeapFirstMaximumCompactionCount           = 3                                   {product}
        uintx HeapMaximumCompactionInterval             = 20                                  {product}
        uintx HeapSizePerGCThread                       = 87241520                            {product}
         bool IgnoreEmptyClassPaths                     = false                               {product}
         bool IgnoreUnrecognizedVMOptions               = false                               {product}
        uintx IncreaseFirstTierCompileThresholdAt       = 50                                  {product}
         bool IncrementalInline                         = true                                {C2 product}
        uintx InitialBootClassLoaderMetaspaceSize       = 4194304                             {product}
        uintx InitialCodeCacheSize                      = 2555904                             {pd product}
        uintx InitialHeapSize                          := 526385152                           {product}
        uintx InitialRAMFraction                        = 64                                  {product}
       double InitialRAMPercentage                      = 1.562500                            {product}
        uintx InitialSurvivorRatio                      = 8                                   {product}
        uintx InitialTenuringThreshold                  = 7                                   {product}
        uintx InitiatingHeapOccupancyPercent            = 45                                  {product}
         bool Inline                                    = true                                {product}
        ccstr InlineDataFile                            =                                     {product}
         intx InlineSmallCode                           = 2000                                {pd product}
         bool InlineSynchronizedMethods                 = true                                {C1 product}
         bool InsertMemBarAfterArraycopy                = true                                {C2 product}
         intx InteriorEntryAlignment                    = 16                                  {C2 pd product}
         intx InterpreterProfilePercentage              = 33                                  {product}
         bool JNIDetachReleasesMonitors                 = true                                {product}
         bool JavaMonitorsInStackTrace                  = true                                {product}
         intx JavaPriority10_To_OSPriority              = -1                                  {product}
         intx JavaPriority1_To_OSPriority               = -1                                  {product}
         intx JavaPriority2_To_OSPriority               = -1                                  {product}
         intx JavaPriority3_To_OSPriority               = -1                                  {product}
         intx JavaPriority4_To_OSPriority               = -1                                  {product}
         intx JavaPriority5_To_OSPriority               = -1                                  {product}
         intx JavaPriority6_To_OSPriority               = -1                                  {product}
         intx JavaPriority7_To_OSPriority               = -1                                  {product}
         intx JavaPriority8_To_OSPriority               = -1                                  {product}
         intx JavaPriority9_To_OSPriority               = -1                                  {product}
         bool LIRFillDelaySlots                         = false                               {C1 pd product}
        uintx LargePageHeapSizeThreshold                = 134217728                           {product}
        uintx LargePageSizeInBytes                      = 0                                   {product}
         bool LazyBootClassLoader                       = true                                {product}
         intx LiveNodeCountInliningCutoff               = 40000                               {C2 product}
         bool LoadExecStackDllInVMThread                = true                                {product}
         bool LogCommercialFeatures                     = false                               {product}
         intx LoopMaxUnroll                             = 16                                  {C2 product}
         intx LoopOptsCount                             = 43                                  {C2 product}
         intx LoopUnrollLimit                           = 60                                  {C2 pd product}
         intx LoopUnrollMin                             = 4                                   {C2 product}
         bool LoopUnswitching                           = true                                {C2 product}
         bool ManagementServer                          = false                               {product}
        uintx MarkStackSize                             = 4194304                             {product}
        uintx MarkStackSizeMax                          = 536870912                           {product}
        uintx MarkSweepAlwaysCompactCount               = 4                                   {product}
        uintx MarkSweepDeadRatio                        = 1                                   {product}
         intx MaxBCEAEstimateLevel                      = 5                                   {product}
         intx MaxBCEAEstimateSize                       = 150                                 {product}
        uintx MaxDirectMemorySize                       = 0                                   {product}
         bool MaxFDLimit                                = true                                {product}
        uintx MaxGCMinorPauseMillis                     = 18446744073709551615                    {product}
        uintx MaxGCPauseMillis                          = 18446744073709551615                    {product}
        uintx MaxHeapFreeRatio                          = 100                                 {manageable}
        uintx MaxHeapSize                              := 8417968128                          {product}
         intx MaxInlineLevel                            = 9                                   {product}
         intx MaxInlineSize                             = 35                                  {product}
         intx MaxJNILocalCapacity                       = 65536                               {product}
         intx MaxJavaStackTraceDepth                    = 1024                                {product}
         intx MaxJumpTableSize                          = 65000                               {C2 product}
         intx MaxJumpTableSparseness                    = 5                                   {C2 product}
         intx MaxLabelRootDepth                         = 1100                                {C2 product}
         intx MaxLoopPad                                = 11                                  {C2 product}
        uintx MaxMetaspaceExpansion                     = 5451776                             {product}
        uintx MaxMetaspaceFreeRatio                     = 70                                  {product}
        uintx MaxMetaspaceSize                          = 18446744073709547520                    {product}
        uintx MaxNewSize                               := 2805989376                          {product}
         intx MaxNodeLimit                              = 75000                               {C2 product}
     uint64_t MaxRAM                                    = 137438953472                        {pd product}
        uintx MaxRAMFraction                            = 4                                   {product}
       double MaxRAMPercentage                          = 25.000000                           {product}
         intx MaxRecursiveInlineLevel                   = 1                                   {product}
        uintx MaxTenuringThreshold                      = 15                                  {product}
         intx MaxTrivialSize                            = 6                                   {product}
         intx MaxVectorSize                             = 32                                  {C2 product}
        uintx MetaspaceSize                             = 21807104                            {pd product}
         bool MethodFlushing                            = true                                {product}
        uintx MinHeapDeltaBytes                        := 524288                              {product}
        uintx MinHeapFreeRatio                          = 0                                   {manageable}
         intx MinInliningThreshold                      = 250                                 {product}
         intx MinJumpTableSize                          = 10                                  {C2 pd product}
        uintx MinMetaspaceExpansion                     = 339968                              {product}
        uintx MinMetaspaceFreeRatio                     = 40                                  {product}
        uintx MinRAMFraction                            = 2                                   {product}
       double MinRAMPercentage                          = 50.000000                           {product}
        uintx MinSurvivorRatio                          = 3                                   {product}
        uintx MinTLABSize                               = 2048                                {product}
         intx MonitorBound                              = 0                                   {product}
         bool MonitorInUseLists                         = false                               {product}
         intx MultiArrayExpandLimit                     = 6                                   {C2 product}
         bool MustCallLoadClassInternal                 = false                               {product}
        uintx NUMAChunkResizeWeight                     = 20                                  {product}
        uintx NUMAInterleaveGranularity                 = 2097152                             {product}
        uintx NUMAPageScanRate                          = 256                                 {product}
        uintx NUMASpaceResizeRate                       = 1073741824                          {product}
         bool NUMAStats                                 = false                               {product}
        ccstr NativeMemoryTracking                      = off                                 {product}
         bool NeedsDeoptSuspend                         = false                               {pd product}
         bool NeverActAsServerClassMachine              = false                               {pd product}
         bool NeverTenure                               = false                               {product}
        uintx NewRatio                                  = 2                                   {product}
        uintx NewSize                                  := 175112192                           {product}
        uintx NewSizeThreadIncrease                     = 5320                                {pd product}
         intx NmethodSweepActivity                      = 10                                  {product}
         intx NmethodSweepCheckInterval                 = 5                                   {product}
         intx NmethodSweepFraction                      = 16                                  {product}
         intx NodeLimitFudgeFactor                      = 2000                                {C2 product}
        uintx NumberOfGCLogFiles                        = 0                                   {product}
         intx NumberOfLoopInstrToAlign                  = 4                                   {C2 product}
         intx ObjectAlignmentInBytes                    = 8                                   {lp64_product}
        uintx OldPLABSize                               = 1024                                {product}
        uintx OldPLABWeight                             = 50                                  {product}
        uintx OldSize                                  := 351272960                           {product}
         bool OmitStackTraceInFastThrow                 = true                                {product}
    ccstrlist OnError                                   =                                     {product}
    ccstrlist OnOutOfMemoryError                        =                                     {product}
         intx OnStackReplacePercentage                  = 140                                 {pd product}
         bool OptimizeFill                              = true                                {C2 product}
         bool OptimizePtrCompare                        = true                                {C2 product}
         bool OptimizeStringConcat                      = true                                {C2 product}
         bool OptoBundling                              = false                               {C2 pd product}
         intx OptoLoopAlignment                         = 16                                  {pd product}
         bool OptoScheduling                            = false                               {C2 pd product}
        uintx PLABWeight                                = 75                                  {product}
         bool PSChunkLargeArrays                        = true                                {product}
         intx ParGCArrayScanChunk                       = 50                                  {product}
        uintx ParGCDesiredObjsFromOverflowList          = 20                                  {product}
         bool ParGCTrimOverflow                         = true                                {product}
         bool ParGCUseLocalOverflow                     = false                               {product}
        uintx ParallelGCBufferWastePct                  = 10                                  {product}
        uintx ParallelGCThreads                         = 13                                  {product}
         bool ParallelGCVerbose                         = false                               {product}
        uintx ParallelOldDeadWoodLimiterMean            = 50                                  {product}
        uintx ParallelOldDeadWoodLimiterStdDev          = 80                                  {product}
         bool ParallelRefProcBalancingEnabled           = true                                {product}
         bool ParallelRefProcEnabled                    = false                               {product}
         bool PartialPeelAtUnsignedTests                = true                                {C2 product}
         bool PartialPeelLoop                           = true                                {C2 product}
         intx PartialPeelNewPhiDelta                    = 0                                   {C2 product}
        uintx PausePadding                              = 1                                   {product}
         intx PerBytecodeRecompilationCutoff            = 200                                 {product}
         intx PerBytecodeTrapLimit                      = 4                                   {product}
         intx PerMethodRecompilationCutoff              = 400                                 {product}
         intx PerMethodTrapLimit                        = 100                                 {product}
         bool PerfAllowAtExitRegistration               = false                               {product}
         bool PerfBypassFileSystemCheck                 = false                               {product}
         intx PerfDataMemorySize                        = 32768                               {product}
         intx PerfDataSamplingInterval                  = 50                                  {product}
        ccstr PerfDataSaveFile                          =                                     {product}
         bool PerfDataSaveToFile                        = false                               {product}
         bool PerfDisableSharedMem                      = false                               {product}
         intx PerfMaxStringConstLength                  = 1024                                {product}
         intx PreInflateSpin                            = 10                                  {pd product}
         bool PreferContainerQuotaForCPUCount           = true                                {product}
         bool PreferInterpreterNativeStubs              = false                               {pd product}
         intx PrefetchCopyIntervalInBytes               = 576                                 {product}
         intx PrefetchFieldsAhead                       = 1                                   {product}
         intx PrefetchScanIntervalInBytes               = 576                                 {product}
         bool PreserveAllAnnotations                    = false                               {product}
         bool PreserveFramePointer                      = false                               {pd product}
        uintx PretenureSizeThreshold                    = 0                                   {product}
         bool PrintAdaptiveSizePolicy                   = false                               {product}
         bool PrintCMSInitiationStatistics              = false                               {product}
         intx PrintCMSStatistics                        = 0                                   {product}
         bool PrintClassHistogram                       = false                               {manageable}
         bool PrintClassHistogramAfterFullGC            = false                               {manageable}
         bool PrintClassHistogramBeforeFullGC           = false                               {manageable}
         bool PrintCodeCache                            = false                               {product}
         bool PrintCodeCacheOnCompilation               = false                               {product}
         bool PrintCommandLineFlags                     = false                               {product}
         bool PrintCompilation                          = false                               {product}
         bool PrintConcurrentLocks                      = false                               {manageable}
         intx PrintFLSCensus                            = 0                                   {product}
         intx PrintFLSStatistics                        = 0                                   {product}
         bool PrintFlagsFinal                          := true                                {product}
         bool PrintFlagsInitial                         = false                               {product}
         bool PrintGC                                   = false                               {manageable}
         bool PrintGCApplicationConcurrentTime          = false                               {product}
         bool PrintGCApplicationStoppedTime             = false                               {product}
         bool PrintGCCause                              = true                                {product}
         bool PrintGCDateStamps                         = false                               {manageable}
         bool PrintGCDetails                            = false                               {manageable}
         bool PrintGCID                                 = false                               {manageable}
         bool PrintGCTaskTimeStamps                     = false                               {product}
         bool PrintGCTimeStamps                         = false                               {manageable}
         bool PrintHeapAtGC                             = false                               {product rw}
         bool PrintHeapAtGCExtended                     = false                               {product rw}
         bool PrintHeapAtSIGBREAK                       = true                                {product}
         bool PrintJNIGCStalls                          = false                               {product}
         bool PrintJNIResolving                         = false                               {product}
         bool PrintOldPLAB                              = false                               {product}
         bool PrintOopAddress                           = false                               {product}
         bool PrintPLAB                                 = false                               {product}
         bool PrintParallelOldGCPhaseTimes              = false                               {product}
         bool PrintPromotionFailure                     = false                               {product}
         bool PrintReferenceGC                          = false                               {product}
         bool PrintSafepointStatistics                  = false                               {product}
         intx PrintSafepointStatisticsCount             = 300                                 {product}
         intx PrintSafepointStatisticsTimeout           = -1                                  {product}
         bool PrintSharedArchiveAndExit                 = false                               {product}
         bool PrintSharedDictionary                     = false                               {product}
         bool PrintSharedSpaces                         = false                               {product}
         bool PrintStringDeduplicationStatistics        = false                               {product}
         bool PrintStringTableStatistics                = false                               {product}
         bool PrintTLAB                                 = false                               {product}
         bool PrintTenuringDistribution                 = false                               {product}
         bool PrintTieredEvents                         = false                               {product}
         bool PrintVMOptions                            = false                               {product}
         bool PrintVMQWaitTime                          = false                               {product}
         bool PrintWarnings                             = true                                {product}
        uintx ProcessDistributionStride                 = 4                                   {product}
         bool ProfileInterpreter                        = true                                {pd product}
         bool ProfileIntervals                          = false                               {product}
         intx ProfileIntervalsTicks                     = 100                                 {product}
         intx ProfileMaturityPercentage                 = 20                                  {product}
         bool ProfileVM                                 = false                               {product}
         bool ProfilerPrintByteCodeStatistics           = false                               {product}
         bool ProfilerRecordPC                          = false                               {product}
        uintx PromotedPadding                           = 3                                   {product}
        uintx QueuedAllocationWarningCount              = 0                                   {product}
        uintx RTMRetryCount                             = 5                                   {ARCH product}
         bool RangeCheckElimination                     = true                                {product}
         intx ReadPrefetchInstr                         = 0                                   {ARCH product}
         bool ReassociateInvariants                     = true                                {C2 product}
         bool ReduceBulkZeroing                         = true                                {C2 product}
         bool ReduceFieldZeroing                        = true                                {C2 product}
         bool ReduceInitialCardMarks                    = true                                {C2 product}
         bool ReduceSignalUsage                         = false                               {product}
         intx RefDiscoveryPolicy                        = 0                                   {product}
         bool ReflectionWrapResolutionErrors            = true                                {product}
         bool RegisterFinalizersAtInit                  = true                                {product}
         bool RelaxAccessControlCheck                   = false                               {product}
        ccstr ReplayDataFile                            =                                     {product}
         bool RequireSharedSpaces                       = false                               {product}
        uintx ReservedCodeCacheSize                     = 251658240                           {pd product}
         bool ResizeOldPLAB                             = true                                {product}
         bool ResizePLAB                                = true                                {product}
         bool ResizeTLAB                                = true                                {pd product}
         bool RestoreMXCSROnJNICalls                    = false                               {product}
         bool RestrictContended                         = true                                {product}
         bool RewriteBytecodes                          = true                                {pd product}
         bool RewriteFrequentPairs                      = true                                {pd product}
         intx SafepointPollOffset                       = 256                                 {C1 pd product}
         intx SafepointSpinBeforeYield                  = 2000                                {product}
         bool SafepointTimeout                          = false                               {product}
         intx SafepointTimeoutDelay                     = 10000                               {product}
         bool ScavengeBeforeFullGC                      = true                                {product}
         intx SelfDestructTimer                         = 0                                   {product}
        uintx SharedBaseAddress                         = 34359738368                         {product}
        ccstr SharedClassListFile                       =                                     {product}
        uintx SharedMiscCodeSize                        = 122880                              {product}
        uintx SharedMiscDataSize                        = 4194304                             {product}
        uintx SharedReadOnlySize                        = 16777216                            {product}
        uintx SharedReadWriteSize                       = 16777216                            {product}
         bool ShowMessageBoxOnError                     = false                               {product}
         intx SoftRefLRUPolicyMSPerMB                   = 1000                                {product}
         bool SpecialEncodeISOArray                     = true                                {C2 product}
         bool SplitIfBlocks                             = true                                {C2 product}
         intx StackRedPages                             = 1                                   {pd product}
         intx StackShadowPages                          = 20                                  {pd product}
         bool StackTraceInThrowable                     = true                                {product}
         intx StackYellowPages                          = 2                                   {pd product}
         bool StartAttachListener                       = false                               {product}
         intx StarvationMonitorInterval                 = 200                                 {product}
         bool StressLdcRewrite                          = false                               {product}
        uintx StringDeduplicationAgeThreshold           = 3                                   {product}
        uintx StringTableSize                           = 60013                               {product}
         bool SuppressFatalErrorMessage                 = false                               {product}
        uintx SurvivorPadding                           = 3                                   {product}
        uintx SurvivorRatio                             = 8                                   {product}
         intx SuspendRetryCount                         = 50                                  {product}
         intx SuspendRetryDelay                         = 5                                   {product}
         intx SyncFlags                                 = 0                                   {product}
        ccstr SyncKnobs                                 =                                     {product}
         intx SyncVerbose                               = 0                                   {product}
        uintx TLABAllocationWeight                      = 35                                  {product}
        uintx TLABRefillWasteFraction                   = 64                                  {product}
        uintx TLABSize                                  = 0                                   {product}
         bool TLABStats                                 = true                                {product}
        uintx TLABWasteIncrement                        = 4                                   {product}
        uintx TLABWasteTargetPercent                    = 1                                   {product}
        uintx TargetPLABWastePct                        = 10                                  {product}
        uintx TargetSurvivorRatio                       = 50                                  {product}
        uintx TenuredGenerationSizeIncrement            = 20                                  {product}
        uintx TenuredGenerationSizeSupplement           = 80                                  {product}
        uintx TenuredGenerationSizeSupplementDecay      = 2                                   {product}
         intx ThreadPriorityPolicy                      = 0                                   {product}
         bool ThreadPriorityVerbose                     = false                               {product}
        uintx ThreadSafetyMargin                        = 52428800                            {product}
         intx ThreadStackSize                           = 1024                                {pd product}
        uintx ThresholdTolerance                        = 10                                  {product}
         intx Tier0BackedgeNotifyFreqLog                = 10                                  {product}
         intx Tier0InvokeNotifyFreqLog                  = 7                                   {product}
         intx Tier0ProfilingStartPercentage             = 200                                 {product}
         intx Tier23InlineeNotifyFreqLog                = 20                                  {product}
         intx Tier2BackEdgeThreshold                    = 0                                   {product}
         intx Tier2BackedgeNotifyFreqLog                = 14                                  {product}
         intx Tier2CompileThreshold                     = 0                                   {product}
         intx Tier2InvokeNotifyFreqLog                  = 11                                  {product}
         intx Tier3BackEdgeThreshold                    = 60000                               {product}
         intx Tier3BackedgeNotifyFreqLog                = 13                                  {product}
         intx Tier3CompileThreshold                     = 2000                                {product}
         intx Tier3DelayOff                             = 2                                   {product}
         intx Tier3DelayOn                              = 5                                   {product}
         intx Tier3InvocationThreshold                  = 200                                 {product}
         intx Tier3InvokeNotifyFreqLog                  = 10                                  {product}
         intx Tier3LoadFeedback                         = 5                                   {product}
         intx Tier3MinInvocationThreshold               = 100                                 {product}
         intx Tier4BackEdgeThreshold                    = 40000                               {product}
         intx Tier4CompileThreshold                     = 15000                               {product}
         intx Tier4InvocationThreshold                  = 5000                                {product}
         intx Tier4LoadFeedback                         = 3                                   {product}
         intx Tier4MinInvocationThreshold               = 600                                 {product}
         bool TieredCompilation                         = true                                {pd product}
         intx TieredCompileTaskTimeout                  = 50                                  {product}
         intx TieredRateUpdateMaxTime                   = 25                                  {product}
         intx TieredRateUpdateMinTime                   = 1                                   {product}
         intx TieredStopAtLevel                         = 4                                   {product}
         bool TimeLinearScan                            = false                               {C1 product}
         bool TraceBiasedLocking                        = false                               {product}
         bool TraceClassLoading                         = false                               {product rw}
         bool TraceClassLoadingPreorder                 = false                               {product}
         bool TraceClassPaths                           = false                               {product}
         bool TraceClassResolution                      = false                               {product}
         bool TraceClassUnloading                       = false                               {product rw}
         bool TraceDynamicGCThreads                     = false                               {product}
         bool TraceGen0Time                             = false                               {product}
         bool TraceGen1Time                             = false                               {product}
        ccstr TraceJVMTI                                =                                     {product}
         bool TraceLoaderConstraints                    = false                               {product rw}
         bool TraceMetadataHumongousAllocation          = false                               {product}
         bool TraceMonitorInflation                     = false                               {product}
         bool TraceParallelOldGCTasks                   = false                               {product}
         intx TraceRedefineClasses                      = 0                                   {product}
         bool TraceSafepointCleanupTime                 = false                               {product}
         bool TraceSharedLookupCache                    = false                               {product}
         bool TraceSuspendWaitFailures                  = false                               {product}
         intx TrackedInitializationLimit                = 50                                  {C2 product}
         bool TransmitErrorReport                       = false                               {product}
         bool TrapBasedNullChecks                       = false                               {pd product}
         bool TrapBasedRangeChecks                      = false                               {C2 pd product}
         intx TypeProfileArgsLimit                      = 2                                   {product}
        uintx TypeProfileLevel                          = 111                                 {pd product}
         intx TypeProfileMajorReceiverPercent           = 90                                  {C2 product}
         intx TypeProfileParmsLimit                     = 2                                   {product}
         intx TypeProfileWidth                          = 2                                   {product}
         intx UnguardOnExecutionViolation               = 0                                   {product}
         bool UnlinkSymbolsALot                         = false                               {product}
         bool Use486InstrsOnly                          = false                               {ARCH product}
         bool UseAES                                    = true                                {product}
         bool UseAESIntrinsics                          = true                                {product}
         intx UseAVX                                    = 2                                   {ARCH product}
         bool UseAdaptiveGCBoundary                     = false                               {product}
         bool UseAdaptiveGenerationSizePolicyAtMajorCollection  = true                                {product}
         bool UseAdaptiveGenerationSizePolicyAtMinorCollection  = true                                {product}
         bool UseAdaptiveNUMAChunkSizing                = true                                {product}
         bool UseAdaptiveSizeDecayMajorGCCost           = true                                {product}
         bool UseAdaptiveSizePolicy                     = true                                {product}
         bool UseAdaptiveSizePolicyFootprintGoal        = true                                {product}
         bool UseAdaptiveSizePolicyWithSystemGC         = false                               {product}
         bool UseAddressNop                             = true                                {ARCH product}
         bool UseAltSigs                                = false                               {product}
         bool UseAutoGCSelectPolicy                     = false                               {product}
         bool UseBMI1Instructions                       = true                                {ARCH product}
         bool UseBMI2Instructions                       = true                                {ARCH product}
         bool UseBiasedLocking                          = true                                {product}
         bool UseBimorphicInlining                      = true                                {C2 product}
         bool UseBoundThreads                           = true                                {product}
         bool UseCLMUL                                  = true                                {ARCH product}
         bool UseCMSBestFit                             = true                                {product}
         bool UseCMSCollectionPassing                   = true                                {product}
         bool UseCMSCompactAtFullCollection             = true                                {product}
         bool UseCMSInitiatingOccupancyOnly             = false                               {product}
         bool UseCRC32Intrinsics                        = true                                {product}
         bool UseCodeCacheFlushing                      = true                                {product}
         bool UseCompiler                               = true                                {product}
         bool UseCompilerSafepoints                     = true                                {product}
         bool UseCompressedClassPointers               := true                                {lp64_product}
         bool UseCompressedOops                        := true                                {lp64_product}
         bool UseConcMarkSweepGC                        = false                               {product}
         bool UseCondCardMark                           = false                               {C2 product}
         bool UseContainerSupport                       = true                                {product}
         bool UseCountLeadingZerosInstruction           = true                                {ARCH product}
         bool UseCountTrailingZerosInstruction          = true                                {ARCH product}
         bool UseCountedLoopSafepoints                  = false                               {C2 product}
         bool UseCounterDecay                           = true                                {product}
         bool UseDivMod                                 = true                                {C2 product}
         bool UseDynamicNumberOfGCThreads               = false                               {product}
         bool UseFPUForSpilling                         = true                                {C2 product}
         bool UseFastAccessorMethods                    = false                               {product}
         bool UseFastEmptyMethods                       = false                               {product}
         bool UseFastJNIAccessors                       = true                                {product}
         bool UseFastStosb                              = true                                {ARCH product}
         bool UseG1GC                                   = false                               {product}
         bool UseGCLogFileRotation                      = false                               {product}
         bool UseGCOverheadLimit                        = true                                {product}
         bool UseGCTaskAffinity                         = false                               {product}
         bool UseHeavyMonitors                          = false                               {product}
         bool UseHugeTLBFS                              = false                               {product}
         bool UseInlineCaches                           = true                                {product}
         bool UseInterpreter                            = true                                {product}
         bool UseJumpTables                             = true                                {C2 product}
         bool UseLWPSynchronization                     = true                                {product}
         bool UseLargePages                             = false                               {pd product}
         bool UseLargePagesInMetaspace                  = false                               {product}
         bool UseLargePagesIndividualAllocation         = false                               {pd product}
         bool UseLinuxPosixThreadCPUClocks              = true                                {product}
         bool UseLockedTracing                          = false                               {product}
         bool UseLoopCounter                            = true                                {product}
         bool UseLoopInvariantCodeMotion                = true                                {C1 product}
         bool UseLoopPredicate                          = true                                {C2 product}
         bool UseMathExactIntrinsics                    = true                                {C2 product}
         bool UseMaximumCompactionOnSystemGC            = true                                {product}
         bool UseMembar                                 = false                               {pd product}
         bool UseMontgomeryMultiplyIntrinsic            = true                                {C2 product}
         bool UseMontgomerySquareIntrinsic              = true                                {C2 product}
         bool UseMulAddIntrinsic                        = true                                {C2 product}
         bool UseMultiplyToLenIntrinsic                 = true                                {C2 product}
         bool UseNUMA                                   = false                               {product}
         bool UseNUMAInterleaving                       = false                               {product}
         bool UseNewLongLShift                          = false                               {ARCH product}
         bool UseOSErrorReporting                       = false                               {pd product}
         bool UseOldInlining                            = true                                {C2 product}
         bool UseOnStackReplacement                     = true                                {pd product}
         bool UseOnlyInlinedBimorphic                   = true                                {C2 product}
         bool UseOprofile                               = false                               {product}
         bool UseOptoBiasInlining                       = true                                {C2 product}
         bool UsePSAdaptiveSurvivorSizePolicy           = true                                {product}
         bool UseParNewGC                               = false                               {product}
         bool UseParallelGC                            := true                                {product}
         bool UseParallelOldGC                          = true                                {product}
         bool UsePerfData                               = true                                {product}
         bool UsePopCountInstruction                    = true                                {product}
         bool UseRDPCForConstantTableBase               = false                               {C2 product}
         bool UseRTMDeopt                               = false                               {ARCH product}
         bool UseRTMLocking                             = false                               {ARCH product}
         bool UseSHA                                    = false                               {product}
         bool UseSHA1Intrinsics                         = false                               {product}
         bool UseSHA256Intrinsics                       = false                               {product}
         bool UseSHA512Intrinsics                       = false                               {product}
         bool UseSHM                                    = false                               {product}
         intx UseSSE                                    = 4                                   {product}
         bool UseSSE42Intrinsics                        = true                                {product}
         bool UseSerialGC                               = false                               {product}
         bool UseSharedSpaces                           = false                               {product}
         bool UseSignalChaining                         = true                                {product}
         bool UseSquareToLenIntrinsic                   = true                                {C2 product}
         bool UseStoreImmI16                            = false                               {ARCH product}
         bool UseStringDeduplication                    = false                               {product}
         bool UseSuperWord                              = true                                {C2 product}
         bool UseTLAB                                   = true                                {pd product}
         bool UseThreadPriorities                       = true                                {pd product}
         bool UseTransparentHugePages                   = false                               {product}
         bool UseTypeProfile                            = true                                {product}
         bool UseTypeSpeculation                        = true                                {C2 product}
         bool UseUnalignedLoadStores                    = false                               {ARCH product}
         bool UseVMInterruptibleIO                      = false                               {product}
         bool UseXMMForArrayCopy                        = true                                {product}
         bool UseXmmI2D                                 = false                               {ARCH product}
         bool UseXmmI2F                                 = false                               {ARCH product}
         bool UseXmmLoadAndClearUpper                   = true                                {ARCH product}
         bool UseXmmRegToRegMoveAll                     = true                                {ARCH product}
         bool VMThreadHintNoPreempt                     = false                               {product}
         intx VMThreadPriority                          = -1                                  {product}
         intx VMThreadStackSize                         = 1024                                {pd product}
         intx ValueMapInitialSize                       = 11                                  {C1 product}
         intx ValueMapMaxLoopSize                       = 8                                   {C1 product}
         intx ValueSearchLimit                          = 1000                                {C2 product}
         bool VerifyMergedCPBytecodes                   = true                                {product}
         bool VerifySharedSpaces                        = false                               {product}
         intx WorkAroundNPTLTimedWaitHang               = 1                                   {product}
        uintx YoungGenerationSizeIncrement              = 20                                  {product}
        uintx YoungGenerationSizeSupplement             = 80                                  {product}
        uintx YoungGenerationSizeSupplementDecay        = 8                                   {product}
        uintx YoungPLABSize                             = 4096                                {product}
         bool ZeroTLAB                                  = false                               {product}
         intx hashCode                                  = 5                                   {product}

3.2 添加JVM参数选项

3.2.1 运行jar包

  • java -Xms50m -Xmx50m -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -jar demo.jar

3.2.2 通过Tomcat运行war包

  • Linux系统下可以在tomcat/bin/catalina.sh中添加类似如下配置:JAVA_OPTS=”-Xms512M -Xmx1024M”。
  • Windows系统下在catalina.bat中添加类似如下配置:set “JAVA_OPTS=-Xms512M -Xmx1024M”。

3.2.3 程序运行过程中

  • 使用jinfo -flag <name>=<value> <pid>设置非Boolean类型参数。
  • 使用jinfo -flag [+|-]<name> <pid>设置Boolean类型参数。

3.3 常用的JVM参数选项

3.3.1 打印设置的XX选项及值

  • -XX:+PrintCommandLineFlags:可以让在程序运行前打印出用户手动设置或者JVM自动设置的XX选项。
  • -XX:+PrintFlagsInitial:表示打印出所有XX选项的默认值。
  • -XX:+PrintFlagsFinal:表示打印出XX选项在运行程序时生效的值。
  • -XX:+PrintVMOptions:打印JVM的参数。

3.3.2 堆、栈、方法区等内存大小设置

3.3.2.1 栈

  • -Xss128k:
    • 设置每个线程的栈大小为128k。
    • 等价于-XX:ThreadStackSize=128k

3.3.2.2 堆内存

  • -Xms3550m:等价于-XX:InitialHeapSize,设置JVM初始堆内存为3550M。
  • -Xmx3550m:等价于-XX:MaxHeapSize,设置JVM最大堆内存为3550M。
  • -Xmn2g:
    • 设置年轻代大小为2G。
    • 官方推荐配置为整个堆大小的3/8。
  • -XX:NewSize=1024m:设置年轻代初始值为1024M。
  • -XX:MaxNewSize=1024m:设置年轻代最大值为1024M。
  • -XX:SurvivorRatio=8:设置年轻代中Eden区与一个Survivor区的比值,默认为8。
  • -XX:+UseAdaptiveSizePolicy:自动选择各区大小比例。
  • -XX:NewRatio=4:设置老年代与年轻代(包括1个Eden和2个Survivor区)的比值。
  • -XX:PretenureSizeThreadshold=1024:
    • 设置让大于此阈值的对象直接分配在老年代,单位为字节。
    • 只对Serial、ParNew收集器有效。
  • -XX:MaxTenuringThreshold=15:
    • 默认值为15。
    • 新生代每次MinorGC后,还存活的对象年龄+1,当对象的年龄大于设置的这个值时就进入老年代。
  • -XX:+PrintTenuringDistribution:让JVM在每次MinorGC后打印出当前使用的Survivor中对象的年龄分布。
  • -XX:TargetSurvivorRatio:表示MinorGC结束后Survivor区域中占用空间的期望比例。

3.3.2.3 方法区

  • 永久代:
    • -XX:PermSize=256m:设置永久代初始值为256M。
    • -XX:MaxPermSize=256m:设置永久代最大值为256M。
  • 元空间:
    • -XX:MetaspaceSize:初始空间大小。
    • -XX:MaxMetaspaceSize:最大空间,默认没有限制。
    • -XX:+UseCompressedOops:压缩对象指针。
    • -XX:+UseCompressedClassPointers:压缩类指针。
    • -XX:CompressedClassSpaceSize:设置Klass Metaspace的大小,默认1G。

3.3.2.4 直接内存

  • -XX:MaxDirectMemorySize:指定DirectMemory容量,若未指定,则默认与Java堆最大值一样。

3.3.3 OutofMemory相关的选项

  • -XX:+HeapDumpOnOutOfMemoryError:表示在内存出现OOM的时候,把Heap转存(Dump)到文件以便后续分析。

  • -XX:+HeapDumpBeforeFullGC:表示在出现FullGC之前,生成Heap转储文件。

  • -XX:HeapDumpPath=<path>:指定heap转存文件的存储路径。

  • -XX:OnOutOfMemoryError:指定一个可行性程序或者脚本的路径,当发生OOM的时候,去执行这个脚本。对OnOutOfMemoryError的运维处理,以部署在linux系统/opt/Server目录下的Server.jar为例:

    • 在run.sh启动脚本中添加jvm参数:-XX:OnOutOfMemoryError=/opt/Server/restart.sh。

    • restart.sh脚本。

      • linux环境:

        1
        2
        3
        4
        5
        6
        7
        #!/bin/bash

        pid=$(ps -ef|grep Server.jar|awk '{if($8=="java") {print $2}}')

        kill -9 $pid

        cd /opt/Server/;sh run.sh
      • Windows环境:

        1
        2
        3
        4
        5
        6
        7
        echo off

        wmic process where Name='java.exe' delete

        cd D:\Server

        start run.bat

3.3.4 垃圾收集器相关选项

3.3.4.1 查看默认垃圾收集器

  • -XX:+PrintCommandLineFlags:查看命令行相关参数(包含使用的垃圾收集器)。
  • 使用命令行指令:jinfo –flag 相关垃圾回收器参数 进程ID。

3.3.4.2 Serial回收器

  • Serial收集器作为HotSpot中Client模式下的默认新生代垃圾收集器。Serial Old是运行在Client模式下默认的老年代的垃圾回收器。
  • -XX:+UseSerialGC:指定年轻代和老年代都使用串行收集器。等价于新生代用Serial GC,且老年代用Serial Old GC。可以获得最高的单线程收集效率。

3.3.4.3 ParNew回收器

  • -XX:+UseParNewGC:手动指定使用ParNew收集器执行内存回收任务。它表示年轻代使用并行收集器,不影响老年代。
  • -XX:ParallelGCThreads=N:限制线程数量,默认开启和CPU数据相同的线程数。

3.3.4.4 Parallel回收器

  • -XX:+UseParallelGC:手动指定年轻代使用Parallel并行收集器执行内存回收任务。

  • -XX:+UseParallelOldGC:手动指定老年代都是使用并行回收收集器。

    • 分别适用于新生代和老年代。默认jdk8是开启的。
    • 上面两个参数,默认开启一个,另一个也会被开启。(互相激活)
  • -XX:ParallelGCThreads:设置年轻代并行收集器的线程数。一般地,最好与CPU数量相等,以避免过多的线程数影响垃圾收集性能。

    • 在默认情况下,当CPU 数量小于8个, ParallelGCThreads 的值等于CPU 数量。
    • 当CPU数量大于8个,ParallelGCThreads 的值等于3+[5*CPU_Count]/8] 。
  • -XX:MaxGCPauseMillis:设置垃圾收集器最大停顿时间(即STW的时间)。单位是毫秒。

    • 为了尽可能地把停顿时间控制在MaxGCPauseMills以内,收集器在工作时会调整Java堆大小或者其他一些参数。
    • 对于用户来讲,停顿时间越短体验越好。但是在服务器端,我们注重高并发,整体的吞吐量。所以服务器端适合Parallel,进行控制。
    • 该参数使用需谨慎。
  • -XX:GCTimeRatio:垃圾收集时间占总时间的比例(= 1 / (N + 1))。用于衡量吞吐量的大小。

    • 取值范围(0,100)。默认值99,也就是垃圾回收时间不超过1%。
    • 与前一个-XX:MaxGCPauseMillis参数有一定矛盾性。暂停时间越长,Radio参数就容易超过设定的比例。
  • -XX:+UseAdaptiveSizePolicy:设置Parallel Scavenge收集器具有自适应调节策略

    • 在这种模式下,年轻代的大小、Eden和Survivor的比例、晋升老年代的对象年龄等参数会被自动调整,已达到在堆大小、吞吐量和停顿时间之间的平衡点。
    • 在手动调优比较困难的场合,可以直接使用这种自适应的方式,仅指定虚拟机的最大堆、目标的吞吐量(GCTimeRatio)和停顿时间(MaxGCPauseMills),让虚拟机自己完成调优工作。

3.3.4.5 CMS回收器

  • -XX:+UseConcMarkSweepGC:手动指定使用CMS收集器执行内存回收任务。

    • 开启该参数后会自动将-XX:+UseParNewGC打开。即:ParNew(Young区用)+CMS(Old区用)+Serial Old的组合。
  • -XX:CMSlnitiatingOccupanyFraction:设置堆内存使用率的阈值,一旦达到该阈值,便开始进行回收。

    • JDK5及以前版本的默认值为68,即当老年代的空间使用率达到68%时,会执行一次CMS 回收。JDK6及以上版本默认值为92%
    • 如果内存增长缓慢,则可以设置一个稍大的值,大的阈值可以有效降低CMS的触发频率,减少老年代回收的次数可以较为明显地改善应用程序性能。反之,如果应用程序内存使用率增长很快,则应该降低这个阈值,以避免频繁触发老年代串行收集器。因此通过该选项便可以有效降低Full GC 的执行次数。
  • -XX:+UseCMSCompactAtFullCollection:用于指定在执行完Full GC后对内存空间进行压缩整理,以此避免内存碎片的产生。不过由于内存压缩整理过程无法并发执行,所带来的问题就是停顿时间变得更长了。

  • -XX:CMSFullGCsBeforeCompaction 设置在执行多少次Full GC后对内存空间进行压缩整理。

  • -XX:ParallelCMSThreads 设置CMS的线程数量。

    • CMS 默认启动的线程数是(ParallelGCThreads+3)/4,ParallelGCThreads 是年轻代并行收集器的线程数。当CPU 资源比较紧张时,受到CMS收集器线程的影响,应用程序的性能在垃圾回收阶段可能会非常糟糕。
  • 另外,CMS收集器还有如下常用参数:

    • -XX:ConcGCThreads:设置并发垃圾收集的线程数,默认该值是基于ParallelGCThreads计算出来的;

    • -XX:+UseCMSInitiatingOccupancyOnly:是否动态可调,用这个参数可以使CMS一直按CMSInitiatingOccupancyFraction设定的值启动;

    • -XX:+CMSScavengeBeforeRemark:强制hotspot虚拟机在cms remark阶段之前做一次minor gc,用于提高remark阶段的速度;

    • -XX:+CMSClassUnloadingEnable:如果有的话,启用回收Perm 区(JDK8之前);

    • -XX:+CMSParallelInitialEnabled:用于开启CMS initial-mark阶段采用多线程的方式进行标记,用于提高标记速度,在Java8开始已经默认开启;

    • -XX:+CMSParallelRemarkEnabled:用户开启CMS remark阶段采用多线程的方式进行重新标记,默认开启;

    • -XX:+ExplicitGCInvokesConcurrent 、-XX:+ExplicitGCInvokesConcurrentAndUnloadsClasses这两个参数用户指定hotspot虚拟在执行System.gc()时使用CMS周期;

    • -XX:+CMSPrecleaningEnabled:指定CMS是否需要进行Pre cleaning这个阶段。

  • JDK9新特性:CMS被标记为Deprecate了(JEP291)。

    • 如果对JDK 9及以上版本的HotSpot虚拟机使用参数-XX:+UseConcMarkSweepGC来开启CMS收集器的话,用户会收到一个警告信息,提示CMS未来将会被废弃。
  • JDK14新特性:删除CMS垃圾回收器(JEP363)。

    • 移除了CMS垃圾收集器,如果在JDK14中使用-XX:+UseConcMarkSweepGC的话,JVM不会报错,只是给出一个warning信息,但是不会exit。JVM会自动回退以默认GC方式启动JVM。

      1
      2
      3
      OpenJDK 64-Bit Server VM warning: Ignoring option UseConcMarkSweepGC; 
      support was removed in 14.0
      and the VM will continue execution using the default collector.

3.3.4.6 G1回收器

  • -XX:+UseG1GC:手动指定使用G1收集器执行内存回收任务。

  • -XX:G1HeapRegionSize:设置每个Region的大小。值是2的幂,范围是1MB到32MB之间,目标是根据最小的Java堆大小划分出约2048个区域。默认是堆内存的1/2000。

  • -XX:MaxGCPauseMillis:设置期望达到的最大GC停顿时间指标(JVM会尽力实现,但不保证达到)。默认值是200ms。

  • -XX:ParallelGCThread:设置STW时GC线程数的值。最多设置为8。

  • -XX:ConcGCThreads:设置并发标记的线程数。将n设置为并行垃圾回收线程数(ParallelGCThreads)的1/4左右。

  • -XX:InitiatingHeapOccupancyPercent;设置触发并发GC周期的Java堆占用率阈值。超过此值,就触发GC。默认值是45。

  • -XX:G1NewSizePercent、-XX:G1MaxNewSizePercent:新生代占用整个堆内存的最小百分比(默认5%)、最大百分比(默认60%)。

  • -XX:G1ReservePercent=10:保留内存区域,防止to space(Survivor中的to区)溢出。

  • Mixed GC调优参数:G1收集器主要涉及到Mixed GC,Mixed GC会回收young 区和部分old区。

    • -XX:InitiatingHeapOccupancyPercent:设置堆占用率的百分比(0到100)达到这个数值的时候触发global concurrent marking(全局并发标记),默认为45%。值为0表示间断进行全局并发标记。
    • -XX:G1MixedGCLiveThresholdPercent:设置Old区的region被回收时候的对象占比,默认占用率为85%。只有Old区的region中存活的对象占用达到了这个百分比,才会在Mixed GC中被回收。

    • -XX:G1HeapWastePercent:在global concurrent marking(全局并发标记)结束之后,可以知道所有的区有多少空间要被回收,在每次young GC之后和再次发生Mixed GC之前,会检查垃圾占比是否达到此参数,只有达到了,下次才会发生Mixed GC。

    • -XX:G1MixedGCCountTarget:一次global concurrent marking(全局并发标记)之后,最多执行Mixed GC的次数,默认是8。

    • -XX:G1OldCSetRegionThresholdPercent:设置Mixed GC收集周期中要收集的Old region数的上限。默认值是Java堆的10%。

3.3.4.7 怎么选择垃圾回收器

  • 优先调整堆的大小让JVM自适应完成。
  • 如果内存小于100M,使用串行收集器。
  • 如果是单核、单机程序,并且没有停顿时间的要求,串行收集器。
  • 如果是多CPU、需要高吞吐量、允许停顿时间超过1秒,选择并行或者JVM自己选择。
  • 如果是多CPU、追求低停顿时间,需快速响应(比如延迟不能超过1秒,如互联网应用),使用并发收集器。官方推荐G1,性能高。现在互联网的项目,基本都是使用G1。
  • 特别说明:
    • 没有最好的收集器,更没有万能的收集;
    • 调优永远是针对特定场景、特定需求,不存在一劳永逸的收集器。

3.3.5 GC日志相关选项

3.3.5.1 常用参数

  • -verbose:gc
    • 输出gc日志信息,默认输出到标准输出。
    • 可以独立使用。
  • -XX:+PrintGC
    • 等同于-verbose:gc 表示打开简化的GC日志。
    • 可以独立使用。
  • -XX:+PrintGCDetails:
    • 在发生垃圾回收时打印内存回收详细的日志,并在进程退出时输出当前内存各区域分配情况。
    • 可以独立使用。
  • -XX:+PrintGCTimeStamps:
    • 输出GC发生时的时间戳。
    • 不可以独立使用,需要配合-XX:+PrintGCDetails使用。
  • -XX:+PrintGCDateStamps:
    • 输出GC发生时的时间戳(以日期的形式,如 2013-05-04T21:53:59.234+0800)。
    • 不可以独立使用,需要配合-XX:+PrintGCDetails使用。
  • -XX:+PrintHeapAtGC:
    • 每一次GC前和GC后,都打印堆信息。
    • 可以独立使用。
  • -Xloggc:<file>:把GC日志写入到一个文件中去,而不是打印到标准输出中。

3.3.5.2 其他参数

  • -XX:+TraceClassLoading:监控类的加载。
  • -XX:+PrintGCApplicationStoppedTime:打印GC时线程的停顿时间。
  • -XX:+PrintGCApplicationConcurrentTime:垃圾收集之前打印出应用未中断的执行时间。
  • -XX:+PrintReferenceGC:记录回收了多少种不同引用类型的引用。
  • -XX:+PrintTenuringDistribution:让JVM在每次MinorGC后打印出当前使用的Survivor中对象的年龄分布。
  • -XX:+UseGCLogFileRotation:启用GC日志文件的自动转储。
  • -XX:NumberOfGClogFiles=1:GC日志文件的循环数目。
  • -XX:GCLogFileSize=1M:控制GC日志文件的大小。

3.3.5 其他参数

  • -XX:+DisableExplicitGC:禁止hotspot执行System.gc(),默认禁用。
  • -XX:ReservedCodeCacheSize=<n>[g|m|k]、-XX:InitialCodeCacheSize=<n>[g|m|k]:指定代码缓存的大小。
  • -XX:+UseCodeCacheFlushing:使用该参数让jvm放弃一些被编译的代码,避免代码缓存被占满时JVM切换到interpreted-only的情况。
  • -XX:+DoEscapeAnalysis:开启逃逸分析。
  • -XX:+UseBiasedLocking:开启偏向锁。
  • -XX:+UseLargePages:开启使用大页面。
  • -XX:+UseTLAB:使用TLAB,默认打开。
  • -XX:+PrintTLAB:打印TLAB的使用情况。
  • -XX:TLABSize:设置TLAB大小。

3.4 按功能性质区分JVM参数选项

  • Java HotSpot VM中-XX:的可配置参数列表进行描述,这些参数可以被松散的聚合成三类:

    • 行为参数(Behavioral Options):用于改变jvm的一些基础行为;

    • 性能调优(Performance Tuning):用于jvm的性能调优;

    • 调试参数(Debugging Options):一般用于打开跟踪、打印、输出等jvm参数,用于显示jvm更加详细的信息。

3.4.1 行为参数(功能开关)

  • -XX:-DisableExplicitGC:禁止调用System.gc();但jvm的gc仍然有效。
  • -XX:+MaxFDLimit:最大化文件描述符的数量限制。
  • -XX:+ScavengeBeforeFullGC:新生代GC优先于Full GC执行。
  • -XX:+UseGCOverheadLimit:在抛出OOM之前限制jvm耗费在GC上的时间比例。
  • -XX:-UseConcMarkSweepGC:对老生代采用并发标记交换算法进行GC。
  • -XX:-UseParallelGC:启用并行GC。
  • -XX:-UseParallelOldGC:对Full GC启用并行,当-XX:-UseParallelGC启用时该项自动启用。
  • -XX:-UseSerialGC:启用串行GC。
  • -XX:+UseThreadPriorities:启用本地线程优先级。

3.4.2 性能调优

  • -XX:LargePageSizeInBytes=4m:设置用于Java堆的大页面尺寸。
  • -XX:MaxHeapFreeRatio=70:GC后java堆中空闲量占的最大比例。
  • -XX:MaxNewSize=size:新生成对象能占用内存的最大值。
  • -XX:MaxPermSize=64m:老生代对象能占用内存的最大值。
  • -XX:MinHeapFreeRatio=40:GC后java堆中空闲量占的最小比例。
  • -XX:NewRatio=2:新生代内存容量与老生代内存容量的比例。
  • -XX:NewSize=2.125m:新生代对象生成时占用内存的默认值。
  • -XX:ReservedCodeCacheSize=32m:保留代码占用的内存容量。
  • -XX:ThreadStackSize=512:设置线程栈大小,若为0则使用系统默认值。
  • -XX:+UseLargePages:使用大页面内存。

3.4.3 调试参数

  • -XX:-CITime:打印消耗在JIT编译的时间。
  • -XX:ErrorFile=./hs_err_pid<pid>.log:保存错误日志或者数据到文件中。
  • -XX:-ExtendedDTraceProbes:开启solaris特有的dtrace探针。
  • -XX:HeapDumpPath=./java_pid<pid>.hprof:指定导出堆信息时的路径或文件名。
  • -XX:-HeapDumpOnOutOfMemoryError:当首次遭遇OOM时导出此时堆中相关信息。
  • -XX:OnError=”<cmd args>;<cmd args>”:出现致命ERROR之后运行自定义命令。
  • -XX:OnOutOfMemoryError=”<cmd args>;<cmd args>”:当首次遭遇OOM时执行自定义命令。
  • -XX:-PrintClassHistogram:遇到Ctrl-Break后打印类实例的柱状信息,与jmap -histo功能相同。
  • -XX:-PrintConcurrentLocks:遇到Ctrl-Break后打印并发锁的相关信息,与jstack -l功能相同。
  • -XX:-PrintCommandLineFlags:打印在命令行中出现过的标记。
  • -XX:-PrintCompilation:当一个方法被编译时打印相关信息。
  • -XX:-PrintGC:每次GC时打印相关信息。
  • -XX:-PrintGC Details:每次GC时打印详细信息。
  • -XX:-PrintGCTimeStamps:打印每次GC的时间戳。
  • -XX:-TraceClassLoading:跟踪类的加载信息。
  • -XX:-TraceClassLoadingPreorder:跟踪被引用到的所有类的加载信息。
  • -XX:-TraceClassResolution:跟踪常量池。
  • -XX:-TraceClassUnloading:跟踪类的卸载信息。
  • -XX:-TraceLoaderConstraints:跟踪类加载器约束的相关信息。

3.5 通过Java代码获取JVM参数

  • Java提供了java.lang.management包用于监视和管理Java虚拟机和Java运行时中的其他组件,它允许本地和远程监控和管理运行的Java虚拟机。其中ManagementFactory这个类还是挺常用的。另外还有Runtime类也可以获取一些内存、CPU核数等相关的数据。

  • 通过这些api可以监控我们的应用服务器的堆内存使用情况,设置一些阈值进行报警等处理。

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    public class MemoryMonitor {
        public static void main(String[] args) {
            MemoryMXBean memorymbean = ManagementFactory.getMemoryMXBean();
            MemoryUsage usage = memorymbean.getHeapMemoryUsage();
            System.out.println("INIT HEAP: " + usage.getInit() / 1024 / 1024 + "m");
            System.out.println("MAX HEAP: " + usage.getMax() / 1024 / 1024 + "m");
            System.out.println("USE HEAP: " + usage.getUsed() / 1024 / 1024 + "m");
            System.out.println("\nFull Information:");
            System.out.println("Heap Memory Usage: " + memorymbean.getHeapMemoryUsage());
            System.out.println("Non-Heap Memory Usage: " + memorymbean.getNonHeapMemoryUsage());

            System.out.println("=======================通过java来获取相关系统状态============================ ");
            System.out.println("当前堆内存大小totalMemory " + (int) Runtime.getRuntime().totalMemory() / 1024 / 1024 + "m");// 当前堆内存大小
            System.out.println("空闲堆内存大小freeMemory " + (int) Runtime.getRuntime().freeMemory() / 1024 / 1024 + "m");// 空闲堆内存大小
            System.out.println("最大可用总堆内存maxMemory " + Runtime.getRuntime().maxMemory() / 1024 / 1024 + "m");// 最大可用总堆内存大小

        }
    }
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    INIT HEAP: 100m
    MAX HEAP: 96m
    USE HEAP: 3m
     
    Full Information:
    Heap Memory Usage: init = 104857600(102400K) used = 3162256(3088K) committed = 100663296(98304K) max = 100663296(98304K)
    Non-Heap Memory Usage: init = 2555904(2496K) used = 5207432(5085K) committed = 8060928(7872K) max = -1(-1K)
    =======================通过java来获取相关系统状态======================== 
    当前堆内存大小totalMemory 96m
    空闲堆内存大小freeMemory 92m
    最大可用总堆内存maxMemory 96m 
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    public class HeapSpaceInitial {
    public static void main(String[] args) {
    //返回Java虚拟机中的堆内存总量
    long initialMemory = Runtime.getRuntime().totalMemory() / 1024 / 1024;
    //返回Java虚拟机试图使用的最大堆内存量
    long maxMemory = Runtime.getRuntime().maxMemory() / 1024 / 1024;
    System.out.println("-Xms : " + initialMemory + "M");    
    System.out.println("-Xmx : " + maxMemory + "M"); 
    System.out.println("系统内存大小为:" + maxMemory * 4.0 / 1024 + "G");
    System.out.println("系统内存大小为:" + initialMemory * 64.0 / 1024 + "G");
    }
    }