jvm 调优命令_java jvm调优工具

2022-11-17 13:47:09 浏览数 (1)

大家好,又见面了,我是你们的朋友全栈君。

1JVM参数

1.1 标准参数

所谓的标准参数,就是不会随着我们JDK 变化而变化版本的参数 这种参数可以通过Java -help查看(和Java -version使用方式一样)

代码语言:javascript复制
Microsoft Windows [版本 10.0.22000.795]
(c) Microsoft Corporation。保留所有权利。
C:Userszwq>java -help
用法: java [-options] class [args...]
(执行类)
或  java [-options] -jar jarfile [args...]
(执行 jar 文件)
其中选项包括:
-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。

1.2 -X 参数(非标准参数)

在jdk某个版本中存在,可能会随着版本变更移除,在标准参数的基础上进行扩展的参数,输入“java -X”命令,能够获得当前JVM支持的所有非标准参数列表(你会发现,其实并不多哦)。

代码语言:javascript复制
C:Userszwq>java -X
-Xmixed           混合模式执行(默认)
-Xint             仅解释模式执行
-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:system
(仅限 Linux)显示系统或容器
配置并继续
-XshowSettings:all
显示所有设置并继续
-XshowSettings:vm 显示所有与 vm 相关的设置并继续
-XshowSettings:properties
显示所有属性设置并继续
-XshowSettings:locale
显示所有与区域设置相关的设置并继续
-X 选项是非标准选项。如有更改,恕不另行通知。

1.3 -XX 参数(非Stable参数)

此类参数各个jvm实现会有所不同(用的最多:JVM调优),将来可能会随时取消,需要慎重使用; 以-XX表示的非Stable参数, JVM(Hotspot)中主要的参数可以大致分为3类

**性能参数(Performance Options):**用于JVM的性能调优和内存分配控制,如初始化内存大小的设置;

**行为参数(Behavioral Options):**用于改变JVM的基础行为,如GC的方式和算法的选择;

**调试参数(Debugging Options):**用于监控、打印、输出等jvm参数,用于显示jvm更加详细的信息;

对于非Stable参数,使用方法有4种: -XX: 启用选项

-XX:- 不启用选项

-XX:= 给选项设置一个数字类型值,可跟单位,例如 32k, 1024m, 2g

-XX:= 给选项设置一个字符串值,例如-XX:HeapDumpPath=./dump.core

1.3.1性能参数

性能参数往往用来定义内存分配的大小和比例,相比于行为参数和调试参数,一个比较明显的区别是性能参数后面往往跟的有数值,常用如下:

参数及其默认值

描述

-XX:NewSize=2.125m

新生代对象生成时占用内存的默认值

-XX:MaxNewSize=size

新生成对象能占用内存的最大值

-XX:MaxPermSize=64m

方法区所能占用的最大内存(非堆内存)

-XX:PermSize=64m

方法区分配的初始内存

-XX:MaxTenuringThreshold=15

对象在新生代存活区切换的次数(坚持过MinorGC的次数,每坚持过一次,该值就增加1),大于该值会进入老年代(年龄阈值)

-XX:MaxHeapFreeRatio=70

GC后java堆中空闲量占的最大比例,大于该值,则堆内存会减少

-XX:MinHeapFreeRatio=40

GC后java堆中空闲量占的最小比例,小于该值,则堆内存会增加

-XX:NewRatio=2

新生代内存容量与老生代内存容量的比例

-XX:ReservedCodeCacheSize= 32m

保留代码占用的内存容量

-XX:ThreadStackSize=512

设置线程栈大小,若为0则使用系统默认值

-XX:LargePageSizeInBytes=4m

设置用于Java堆的大页面尺寸

-XX:PretenureSizeThreshold= size

大于该值的对象直接晋升入老年代(这种对象少用为好)

-XX:SurvivorRatio=8

Eden区域Survivor区的容量比值,如默认值为8,代表Eden:Survivor1:Survivor2=8:1:1

1.3.2行为参数

行为参数主要用来选择使用什么样的垃圾收集器组合,以及控制运行过程中的GC策略等

参数及其默认值

描述

-XX: UseSerialGC

启用串行GC,即采用Serial Serial Old模式

-XX: UseParallelGC

启用并行GC,即采用Parallel Scavenge Serial Old收集器组合(-Server模式下的默认组合)

-XX:GCTimeRatio=99

设置用户执行时间占总时间的比例(默认值99,即1%的时间用于GC)

-XX:MaxGCPauseMillis=time

设置GC的最大停顿时间(这个参数只对Parallel Scavenge有效)

-XX: UseParNewGC

使用ParNew Serial Old收集器组合

-XX:ParallelGCThreads

设置执行内存回收的线程数,在 UseParNewGC的情况下使用

-XX: UseParallelOldGC

使用Parallel Scavenge Parallel Old组合收集器

-XX: UseConcMarkSweepGC

使用ParNew CMS Serial Old组合并发收集,优先使用ParNew CMS,当用户线程内存不足时,采用备用方案Serial Old收集。

-XX:-DisableExplicitGC

禁止调用System.gc();但jvm的gc仍然有效

-XX: ScavengeBeforeFullGC

新生代GC优先于Full GC执行

1.3.3调试参数

调试参数,主要用于监控和打印GC的信息

参数及其默认值

描述

-XX:-CITime

打印消耗在JIT编译的时间

-XX:ErrorFile=./hs_err_pid.log

保存错误日志或者数据到文件中

-XX:-ExtendedDTraceProbes

开启solaris特有的dtrace探针

-XX:HeapDumpPath=./java_pid.hprof

指定导出堆信息时的路径或文件名

-XX:-HeapDumpOnOutOfMemoryError

当首次遭遇OOM时导出此时堆中相关信息

-XX:OnError=“;”

出现致命ERROR之后运行自定义命令

-XX:OnOutOfMemoryError=“;”

当首次遭遇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

跟踪类加载器约束的相关信息

1.4其他参数(一定要背下来)

-Xms100M  等价于  -XX:InitialHeapSize=100M 堆的初始化大小 -Xmx100M  等价于  -XX:MaxHeapSize=100M 堆的最大内存 -Xss100k  等价于  -XX:ThreadStackSize=100k 虚拟机栈的大小 默认是1m

2设置参数的方式

  1. 开发工具 IDEA 、Eclipse 在run configuration 里设置VM option 运行jar包, java -XX: UseG1GC xxx.jar
  2. 线上环境 web容器:Tomcat, startup.sh -> catalina.sh(卡特琳娜) 里设置JVM 参数 jsp jinfo 查看某个java进程的参数,然后再调整设置
  3. 真实调优 java -XX: UseG1GC xxx.jar

3 五大常用命令(一定要背下来)

3.1 JPS

查看java进程id

查看当前系统上,正在运行的java 进程 id列表和运行的类全限定名

3.2 jinfo

查看参数

  1. 实时查看某个进程id的jvm 参数
  1. 查看某个进程id的所有jvm参数
  1. 修改我们可以 manageable 热更新的参数

3.3 jstat

查看性能 类加载、内存、垃圾收集情况、 JIT 实时编译的运行时数据

虚拟机统计信息监控工具,本地或者远程虚拟机进程中的类加载、内存、垃圾收集、即时编译等运行时数据

参数解释:

option 参数

解释

-class

显示ClassLoad的相关信息

-compiler

显示JIT编译的相关信息

-gc

显示和gc相关的堆信息-

-gccapacity

显示各个代的容量以及使用情况

-gccause

显示垃圾回收的相关信息(通-gcutil),同时显示最后一次或当前正在发生的垃圾回收的诱因

-gcnew

显示新生代的信息

-gcnewcapacity

显示新生代大小和使用情况

-gcold

显示老年代和永久代的信息

-gcoldcapacity

显示老年代的大小

-gcpermcapacity

显示永久代的大小

-gcutil

显示垃圾收集信息

-printcompilation

输出JIT编译的方法信息

参数

解释

-t

可以在打印的列上加上Timestamp列,用于显示系统运行的时间

-h

可以在周期性数据的时候,可以在指定输出多少行以后输出一次表头

interval

执行每次的间隔时间,单位为毫秒

count

用于指定输出多少次记录,缺省则会一直打印

举几个例子:

  1. 查看类装载信息

jstat -class PID 1000 10 查看某个java进程的类装载信息,每1000毫秒输出一 次,共输出10次

  1. 查看垃圾收集信息 jstat -gc PID 1000 10

参数

解析

S0C

Survivor0(幸存者0区)大小(KB)

S1C

Survivor1(幸存者1区)大小(KB)

S0U

Survivor0(幸存者0区)已使用大小(KB)

S1C

Survivor1(幸存者1区)以使用大小(KB)

EC

Eeden(伊甸区)大小(KB)

EU

Eden(伊甸区)已使用大小(KB)

OC

老年代大小(KB)

OU

老年代已使用大小 (KB)

OC

老年代大小(KB)

OU

老年代已使用大小(KB)

PC

Perm永久代大小(KB)

PU

Perm永久代已使用大小(KB)

YGC

新生代GC个数

YGCT

新生代GC的耗时(秒

FGC

Full GC次数

FGCT

Full GC耗时(秒)

GCT

GC总耗时(秒)

C = Capacity 容量 U = Used 已使用的意思 P = permanent 永久代 S = Survivor 幸存者 Y = Young T = time 时间 E = Eden

3.4 jstack 堆栈信息

查看线程堆栈信息

jstack pid 查看线程堆栈

3.5jmap

生成堆栈转储快照

The jmap command prints shared object memory maps or heap memory details of a specified process, core file, or remote debug server.

打印堆内存相关信息

代码语言:javascript复制
jmap -heap PID

dump 堆内存相关信息

jmap -dump:format=b,file=heap.hprof 44808

要是在发生堆内存溢出的时候,能自动dump出该文件就好了

一般在开发中,JVM参数可以加上下面两句,这样内存溢出时,会自动dump出该文件

-XX: HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heap.hprof

-Xmx20M -Xms20M -XX: HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heap.hprof 启动,然后访问 localhost:9090/heap

在服务器 在tomcat启动参数中加入两个参数 -XX: HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/export/tomcat/xxx/xx/heap.hprof

在排查的的时候

jmap -dump:format=b,file=heap.hprof 44808

一般dump下来的文件可以结合工具来分析

4调优常用工具

jconsole、jvisualvm、MAT 在分析Dump文件的时候用 GC Viewer 分析GC日志

4.1jconsole

Jconsole工具是JDK自带的可视化监控工具。查看java应用程序的运行情况、监控堆信息、永久区使用情况、类加载情况等等

命令行中输入:jconsole 即可

4.2jvisualvm

监控本地java进程 可监控本地java进程的CPU,类,线程等等。 监控远端java进程

比如监控客户端的tomcat

演示一下部署在服务器上的tomcat

(1)在visualvm中选中“远程”,右击“添加” (2)主机名上写服务器的ip地址,比如31.100.39.63,然后点击“确定” (3)右击该主机“31.100.39.63”,添加“JMX”[也就是通过JMX技术具体监控远端服务器哪个Java进程] (4)要想让服务器上的tomcat被连接,需要改一下 bin/catalina.sh 这个文件

注意下面的8998不要和服务器上其他端口冲突

JAVA_OPTS=“$JAVA_OPTS -Dcom.sun.management.jmxremote – Djava.rmi.server.hostname=31.100.39.63 – Dcom.sun.management.jmxremote.port=8998 – Dcom.sun.management.jmxremote.ssl=false – Dcom.sun.management.jmxremote.authenticate=true – Dcom.sun.management.jmxremote.access.file=…/conf/jmxremote.access -Dcom.sun.management.jmxremote.password.file=…/conf/jmxremote.pass word”

(5)在 …/conf 文件中添加两个文件jmxremote.access和jmxremote.password jmxremote.access 文件

guest readonly manager readwrite

jmxremote.password 文件

guest guest manager manager

代码语言:javascript复制
授予权限 : chmod 600 *jmxremot*

(6)将连接服务器地址改为公网ip地址 (7)设置上述端口对应的安全策略和防火墙策略 (8)启动tomcat,来到bin目录

代码语言:javascript复制
./startup.sh

(9)查看tomcat启动日志以及端口监听

代码语言:javascript复制
tail -f ../logs/catalina.out lsof -i tcp:8080

(10)查看8998监听情况,可以发现多开了几个端口

代码语言:javascript复制
lsof -i:8998 得到PID netstat -antup | grep PID

(11)在刚才的JMX中输入8998端口,并且输入用户名和密码则登录成功

端口:8998 用户名:manager 密码:manager

4.3 MAT

Java堆分析器,用于查找内存泄漏 Heap Dump,称为堆转储文件,是Java进程在某个时间内的快照 下载地址 :https://www.eclipse.org/mat/downloads.php

Dump信息包含的内容

  • All Objects Class, fifields, primitive values and references
  • All Classes Classloader, name, super class, static fifields
  • Garbage Collection Roots Objects defifined to be reachable by the JVM
  • Thread Stacks and Local Variables The call-stacks of threads at the moment of the snapshot, and per-frame information about local objects

获取Dump文件 手动

代码语言:javascript复制
jmap -dump:format=b,file=heap.hprof 44808

自动 idea设置VM参数、或者运行jar包时 设置

代码语言:javascript复制
-XX: HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heap.hprof

4.4使用MAT

Histogram Histogram [ˈhɪstəɡræm] 柱状图 :可以列出内存中的对象,对象的个数及其大小

Class Name:类名称,java类名 Objects:类的对象的数量,这个对象被创建了多少个 Shallow Heap:一个对象内存的消耗大小,不包含对其他对象的引用 Retained Heap: 是shallow Heap的总和,即该对象被GC之后所能回收到内存的总和。

右击类名—>List Objects—>with incoming references—>列出该类的实例

右击Java对象名—>Merge Shortest Paths to GC Roots—>exclude all …—>找到GC Root以及原因

Leak[li:k] Suspects [səˈspekts] 查找并分析内存泄漏的可能原因

Reports—>Leak Suspects—>Details

Top Consumers

列出大对象

5调优实战分析

5.1生产环境事故

java 进程突然消失了

线上程序异常,首先你得知道Java 的异常体系,分别为 Exception、Error 两种体系,对于Exception我们程序员一般分为受检异常和非受检异常,大部分异常都能通过log文件分析。

Error异常体系发生的原因有jvm自身的bug,应用程序错误,jvm参数配置不当,服务器资源不足,jni调用错误等等。当我们JVM 出现致命错误,会生成一个错误的文件,hs_error_pid.log,里面有导致 JVM 崩溃的重要信息。

比如: 线程信息、所有线程信息、堆信息、gc相关记录

解决思路:

  1. 业务日志 没有错误
  2. JVM 错误日志 hs_error_pid.log

可以通过设置以下这个参数,来指定错误日志路径 -XX:ErrorFile=./

通过分析我们的 jvm 错误日志定位问题,然后解决。

5.2程序监控调优

前提:java 应用程序必然是正常运行的。.

目的:减少GC 频率,减少Full GC

发现现象才去解决?比如说 CPU 飙升、内存飙升

  1. 打印dump文件分析堆内存
  2. 打印GC日志,分析日志文件

-Xms30m -Xmx30m -XX: HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=heap1.hprof -XX: PrintGCDetails -Xloggc:gc.log

  1. 定位问题
  2. 调节参数
  3. 观察结果
  4. 重复4、5步

5.3GC的次数频繁怎么办?

打印出GC日志,到底是minorGC频繁还是majorGC频繁,结合工具看一下 (1)适当增加堆内存的空间 (2)选择垃圾收集器不合适 (3)(如果是G1)停顿时间是否太严格,或者堆存的使用率可以调成高于45%

5.4几个面试问题

调优无非就是 减少GC次数、减少Full GC,提高应用程序的吞吐量

(1)内存泄漏与内存溢出的区别 内存泄漏:对象无法得到及时的回收,持续占用内存空间,从而造成内存空间的浪费。 内存溢出:内存泄漏到一定的程度就会导致内存溢出,但是内存溢出也有可能是大对象导致的。 (2)young gc会有stw吗? 不管什么 GC,都会有 stop-the-world,只是发生时间的长短。 (3)major gc和full gc的区别 major gc指的是老年代的gc,而full gc等于young old metaspace的gc。 (4)G1与CMS的区别是什么 CMS 用于老年代的回收,而 G1 用于新生代和老年代的回收。 G1 使用了 Region 方式对堆内存进行了划分,且基于标记整理算法实现,整体减少了垃圾碎片的产生。 (5)什么是直接内存 直接内存是在java堆外的、直接向系统申请的内存空间。通常访问直接内存的速度会优于Java堆。因此出于性能的考虑,读写频繁的场合可能会考虑使用直接内存。 (6)不可达的对象一定要被回收吗? 即使在可达性分析法中不可达的对象,也并非是“非死不可”的,这时候它们暂时处于“缓刑阶段”,要真正宣告一个对象死亡,至少要经历两次标记过程;可达性分法中不可达的对象被第一次标记并且进行一次筛选,筛选的条件是此对象是否有必要执行fifinalize 方法。当对象没有覆盖 fifinalize 方法,或 fifinalize 方法已经被虚拟机调用过时,虚拟机将这两种情况视为没有必要执行。 被判定为需要执行的对象将会被放在一个队列中进行第二次标记,除非这个对象与引用链上的任何一个对象建立关联,否则就会被真的回收。 (7)方法区中的无用类回收 方法区主要回收的是无用的类,那么如何判断一个类是无用的类的呢?判定一个常量是否是“废弃常量”比较简单,而要判定一个类是否是“无用的类”的条件则相对苛刻许多。 类需要同时满足下面 3 个条件才能算是 “无用的类” : 该类所有的实例都已经被回收,也就是 Java 堆中不存在该类的任何实例。 加载该类的 ClassLoader 已经被回收。 该类对应的 java.lang.Class 对象没有在任何地方被引用,无法在任何地方通过反射访问该类的方法。

虚拟机可以对满足上述 3 个条件的无用类进行回收,这里说的仅仅是“可以”,而并不是和对象一样不使用了就会必然被回收

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/234245.html原文链接:https://javaforall.cn

0 人点赞