一、jps,查看虚拟机进程的命令
参数说明
-q:只输出进程 ID
-m:输出传入 main 方法的参数
-l:输出完全的包名,应用主类名,jar的完全路径名
-v:输出jvm参数
二、jstat,查看虚拟机统计信息监视命令
jstat -gcutil 进程id 多少毫秒查询一次 共查询多少次 ,查看垃圾收集的状况,例如下图,进程号10066 ,1000毫秒查询一次,总共查询10次
这命令主要查看堆内存gc情况,垃圾对象首先进入的是新生代Eden区,然后Eden没有回收掉,进入S0,还没有回收掉,进入S1区,当S1区使用满了后,会发生一次YGC,但是不会是应用停止。这时垃圾对象还没有被回收掉,就会进入到老年代Old区,当Old区使用满了后,就会发生一次FGC,FGC会导致应用停止,所以不能频发的发生FGC,FGC代表发生FGC的次数,FGCT代表发生FGC的时间,如果FGC很大,就要定位是什么原因导致的频繁发生FGC。这时可以使用jmap工具定位,或者Jvisualvm工具定位。
三、jinfo 查看java配置信息命令
1、jinfo process_id 输出全部的参数和系统属性
例如jinfo 10066
[njl@web /]$ jinfo 10066
Attaching to process ID 10066, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.131-b11
Java System Properties:
java.runtime.name = Java(TM) SE Runtime Environment
java.vm.version = 25.131-b11
sun.boot.library.path = /home/njl/jdk1.8/jre/lib/amd64
java.protocol.handler.pkgs = org.apache.catalina.webresources
shared.loader =
java.vendor.url = http://java.oracle.com/
java.vm.vendor = Oracle Corporation
path.separator = :
file.encoding.pkg = sun.io
java.vm.name = Java HotSpot(TM) 64-Bit Server VM
java.util.logging.config.file = /home/njl/apache-tomcat-8.5.15/conf/logging.properties
tomcat.util.buf.StringCache.byte.enabled = true
sun.os.patch.level = unknown
sun.java.launcher = SUN_STANDARD
user.country = US
tomcat.util.scan.StandardJarScanFilter.jarsToScan = log4j-web*.jar,log4j-taglib*.jar,log4javascript*.jar,slf4j-taglib*.jar
user.dir = /home/njl/apache-tomcat-8.5.15/bin
java.vm.specification.name = Java Virtual Machine Specification
java.runtime.version = 1.8.0_131-b11
java.awt.graphicsenv = sun.awt.X11GraphicsEnvironment
os.arch = amd64
java.endorsed.dirs = /home/njl/jdk1.8/jre/lib/endorsed
line.separator =
java.io.tmpdir = /home/njl/apache-tomcat-8.5.15/temp
java.vm.specification.vendor = Oracle Corporation
java.util.logging.manager = org.apache.juli.ClassLoaderLogManager
java.naming.factory.url.pkgs = org.apache.naming
os.name = Linux
sun.jnu.encoding = UTF-8
java.library.path = /usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib
java.class.version = 52.0
java.specification.name = Java Platform API Specification
sun.management.compiler = HotSpot 64-Bit Tiered Compilers
os.version = 3.10.0-693.2.2.el7.x86_64
java.util.concurrent.ForkJoinPool.common.threadFactory = org.apache.catalina.startup.SafeForkJoinWorkerThreadFactory
user.home = /home/njl
user.timezone = Asia/Shanghai
catalina.useNaming = true
java.awt.printerjob = sun.print.PSPrinterJob
file.encoding = UTF-8
java.specification.version = 1.8
tomcat.util.scan.StandardJarScanFilter.jarsToSkip = bootstrap.jar,commons-daemon.jar,tomcat-juli.jar,annotations-api.jar,el-api.jar,jsp-api.jar,servlet-api.jar,websocket-api.jar,jaspic-api.jar,catalina.jar,catalina-ant.jar,catalina-ha.jar,catalina-storeconfig.jar,catalina-tribes.jar,jasper.jar,jasper-el.jar,ecj-*.jar,tomcat-api.jar,tomcat-util.jar,tomcat-util-scan.jar,tomcat-coyote.jar,tomcat-dbcp.jar,tomcat-jni.jar,tomcat-websocket.jar,tomcat-i18n-en.jar,tomcat-i18n-es.jar,tomcat-i18n-fr.jar,tomcat-i18n-ja.jar,tomcat-juli-adapters.jar,catalina-jmx-remote.jar,catalina-ws.jar,tomcat-jdbc.jar,tools.jar,commons-beanutils*.jar,commons-codec*.jar,commons-collections*.jar,commons-dbcp*.jar,commons-digester*.jar,commons-fileupload*.jar,commons-httpclient*.jar,commons-io*.jar,commons-lang*.jar,commons-logging*.jar,commons-math*.jar,commons-pool*.jar,jstl.jar,taglibs-standard-spec-*.jar,geronimo-spec-jaxrpc*.jar,wsdl4j*.jar,ant.jar,ant-junit*.jar,aspectj*.jar,jmx.jar,h2*.jar,hibernate*.jar,httpclient*.jar,jmx-tools.jar,jta*.jar,log4j*.jar,mail*.jar,slf4j*.jar,xercesImpl.jar,xmlParserAPIs.jar,xml-apis.jar,junit.jar,junit-*.jar,hamcrest-*.jar,easymock-*.jar,cglib-*.jar,objenesis-*.jar,ant-launcher.jar,cobertura-*.jar,asm-*.jar,dom4j-*.jar,icu4j-*.jar,jaxen-*.jar,jdom-*.jar,jetty-*.jar,oro-*.jar,servlet-api-*.jar,tagsoup-*.jar,xmlParserAPIs-*.jar,xom-*.jar
catalina.home = /home/njl/apache-tomcat-8.5.15
user.name = njl
java.class.path = /home/njl/apache-tomcat-8.5.15/bin/bootstrap.jar:/home/njl/apache-tomcat-8.5.15/bin/tomcat-juli.jar
java.naming.factory.initial = org.apache.naming.java.javaURLContextFactory
package.definition = sun.,java.,org.apache.catalina.,org.apache.coyote.,org.apache.jasper.,org.apache.naming.,org.apache.tomcat.
java.vm.specification.version = 1.8
sun.arch.data.model = 64
sun.java.command = org.apache.catalina.startup.Bootstrap start
java.home = /home/njl/jdk1.8/jre
user.language = en
java.specification.vendor = Oracle Corporation
awt.toolkit = sun.awt.X11.XToolkit
java.vm.info = mixed mode
java.version = 1.8.0_131
java.ext.dirs = /home/njl/jdk1.8/jre/lib/ext:/usr/java/packages/lib/ext
sun.boot.class.path = /home/njl/jdk1.8/jre/lib/resources.jar:/home/njl/jdk1.8/jre/lib/rt.jar:/home/njl/jdk1.8/jre/lib/sunrsasign.jar:/home/njl/jdk1.8/jre/lib/jsse.jar:/home/njl/jdk1.8/jre/lib/jce.jar:/home/njl/jdk1.8/jre/lib/charsets.jar:/home/njl/jdk1.8/jre/lib/jfr.jar:/home/njl/jdk1.8/jre/classes
server.loader =
java.vendor = Oracle Corporation
catalina.base = /home/njl/apache-tomcat-8.5.15
jdk.tls.ephemeralDHKeySize = 2048
file.separator = /
java.vendor.url.bug = http://bugreport.sun.com/bugreport/
common.loader = "${catalina.base}/lib","${catalina.base}/lib/*.jar","${catalina.home}/lib","${catalina.home}/lib/*.jar"
sun.io.unicode.encoding = UnicodeLittle
sun.cpu.endian = little
package.access = sun.,org.apache.catalina.,org.apache.coyote.,org.apache.jasper.,org.apache.tomcat.
sun.cpu.isalist =
VM Flags:
Non-default VM flags: -XX:CICompilerCount=2 -XX:InitialHeapSize=31457280 -XX:MaxHeapSize=482344960 -XX:MaxNewSize=160759808 -XX:MinHeapDeltaBytes=196608 -XX:NewSize=10485760 -XX:OldSize=20971520 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops
Command line: -Djava.util.logging.config.file=/home/njl/apache-tomcat-8.5.15/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dcatalina.base=/home/njl/apache-tomcat-8.5.15 -Dcatalina.home=/home/njl/apache-tomcat-8.5.15 -Djava.io.tmpdir=/home/njl/apache-tomcat-8.5.15/temp
2、jinfo -flags process_id 查看jvm的参数
[njl@web /]$ jinfo -flags 10066
Attaching to process ID 10066, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.131-b11
Non-default VM flags: -XX:CICompilerCount=2 -XX:InitialHeapSize=31457280 -XX:MaxHeapSize=482344960 -XX:MaxNewSize=160759808 -XX:MinHeapDeltaBytes=196608 -XX:NewSize=10485760 -XX:OldSize=20971520 -XX:+UseCompressedClassPointers -XX:+UseCompressedOops
Command line: -Djava.util.logging.config.file=/home/njl/apache-tomcat-8.5.15/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dcatalina.base=/home/njl/apache-tomcat-8.5.15 -Dcatalina.home=/home/njl/apache-tomcat-8.5.15 -Djava.io.tmpdir=/home/njl/apache-tomcat-8.5.15/temp
3、虚拟机的全部参数可以通过下面的命令查看:
java -XX:+PrintFlagsFinal -version | grep manageable
[njl@web /]$ java -XX:+PrintFlagsFinal -version | grep manageable
intx CMSAbortablePrecleanWaitMillis = 100 {manageable}
intx CMSTriggerInterval = -1 {manageable}
intx CMSWaitDuration = 2000 {manageable}
bool HeapDumpAfterFullGC = false {manageable}
bool HeapDumpBeforeFullGC = false {manageable}
bool HeapDumpOnOutOfMemoryError = false {manageable}
ccstr HeapDumpPath = {manageable}
uintx MaxHeapFreeRatio = 70 {manageable}
uintx MinHeapFreeRatio = 40 {manageable}
bool PrintClassHistogram = false {manageable}
bool PrintClassHistogramAfterFullGC = false {manageable}
bool PrintClassHistogramBeforeFullGC = false {manageable}
bool PrintConcurrentLocks = false {manageable}
bool PrintGC = false {manageable}
bool PrintGCDateStamps = false {manageable}
bool PrintGCDetails = false {manageable}
bool PrintGCID = false {manageable}
bool PrintGCTimeStamps = false {manageable}
java version "1.8.0_131"
Java(TM) SE Runtime Environment (build 1.8.0_131-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)
四、jmap,用于生成堆转储快照,不用命令还可以用其他的方式,比如,-XX:+HeapDumpOnOutOfMemoryError参数,可以让虚拟机在OOM异常出现之后自动生成dump文件。jmap不仅获取dump文件,还可以查询finalize执行队列,java堆和永久代的详细信息。此命令主要是生成堆dump文件使用的,定位堆内存溢出,代码的位置,因为篇幅较长,就不在这细说了,如果大家感兴趣可以看我的另外一篇博客,https://blog.csdn.net/qq_30353203/article/details/68063733,如何使用jmap定位堆内存溢出稳定。
-dump
dump堆到文件,format指定输出格式,live指明是活着的对象,file指定文件名
[njl@web ~]$ jmap -dump:live,format=b,file=dump.hprof 10066
Dumping heap to /home/njl/dump.hprof ...
Heap dump file created
-heap
打印heap的概要信息,GC使用的算法,heap的配置及使用情况,可以用此来判断内存目前的使用情况以及垃圾回收情况
[njl@web ~]$ jmap -heap 10066
Attaching to process ID 10066, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.131-b11
using thread-local object allocation.
Mark Sweep Compact GC
Heap Configuration:
MinHeapFreeRatio = 40
MaxHeapFreeRatio = 70
MaxHeapSize = 482344960 (460.0MB)
NewSize = 10485760 (10.0MB)
MaxNewSize = 160759808 (153.3125MB)
OldSize = 20971520 (20.0MB)
NewRatio = 2
SurvivorRatio = 8
MetaspaceSize = 21807104 (20.796875MB)
CompressedClassSpaceSize = 1073741824 (1024.0MB)
MaxMetaspaceSize = 17592186044415 MB
G1HeapRegionSize = 0 (0.0MB)
Heap Usage:
New Generation (Eden + 1 Survivor Space):
capacity = 14745600 (14.0625MB)
used = 261600 (0.249481201171875MB)
free = 14484000 (13.813018798828125MB)
1.7740885416666667% used
Eden Space:
capacity = 13107200 (12.5MB)
used = 261600 (0.249481201171875MB)
free = 12845600 (12.250518798828125MB)
1.995849609375% used
From Space:
capacity = 1638400 (1.5625MB)
used = 0 (0.0MB)
free = 1638400 (1.5625MB)
0.0% used
To Space:
capacity = 1638400 (1.5625MB)
used = 0 (0.0MB)
free = 1638400 (1.5625MB)
0.0% used
tenured generation:
capacity = 32751616 (31.234375MB)
used = 17664680 (16.846351623535156MB)
free = 15086936 (14.388023376464844MB)
53.935292841733364% used
16490 interned Strings occupying 2105240 bytes.
-finalizerinfo
打印等待回收的对象信息
[njl@web ~]$ jmap -finalizerinfo 10066
Attaching to process ID 10066, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.131-b11
Number of objects pending for finalization: 0
Number of objects pending for finalization: 0 说明当前F-QUEUE队列中并没有等待Fializer线程执行finalizer方法的对象。
-histo
打印堆的对象统计,包括对象数、内存大小等等。jmap -histo:live 这个命令执行,JVM会先触发gc,然后再统计信息
[njl@web ~]$ jmap -histo:live 10066 | more
num #instances #bytes class name
----------------------------------------------
1: 53441 8252392 [C
2: 52522 1260528 java.lang.String
3: 5867 659824 java.lang.Class
4: 7256 638528 java.lang.reflect.Method
5: 977 628576 [B
6: 17330 554560 java.util.HashMap$Node
7: 11941 382112 java.util.concurrent.ConcurrentHashMap$Node
8: 5846 341672 [Ljava.lang.Object;
9: 1522 220056 [Ljava.util.HashMap$Node;
10: 2912 157816 [I
11: 4627 148064 java.lang.ref.WeakReference
12: 6911 110576 java.lang.Object
13: 113 109872 [Ljava.util.concurrent.ConcurrentHashMap$Node;
14: 2527 101080 java.util.LinkedHashMap$Entry
五、jhat,查看虚拟机堆内存命令
主要是用来分析java堆的命令,它与jmap搭配使用,来分析jmap生成的堆转储快照,jhat内置了一个微型的HTTP/HTML服务器,生成的dump文件的分析结果后,可以在浏览器中查看。但是一般不会直接用jhat这命令分析dump文件,因为,一是一般不会在部署应用的服务器上直接分析dump文件,即使这样做,也会尽量将dump文件复制到其他机器上,因为分析工作是一个耗时而且消耗硬件资源的过程,既然要在其他机器上进行进行,就没有必要使用命令行。二、是有个一可视化工具VisualVM和Ecplise里的插件MAT,比jhat可以更好的分析堆转储快照。
使用命令jmap,打出的堆dump文件,可以使用jhat这命令,分析堆文件
[njl@web ~]$ jhat dump.hprof
Reading from dump.hprof...
Dump file created Mon Jan 21 20:19:06 CST 2019
Snapshot read, resolving...
Resolving 245665 objects...
Chasing references, expect 49 dots.................................................
Eliminating duplicate references.................................................
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.
上图中使用jhat命令打开了之前dump出来的堆快照文件,可以看到,命令成功执行后会在命令执行的本机启动一个http服务,可以在浏览器上打开本机的7000端口查看详细的分析结果:
页面中显示了所有非平台类信息,点击链接进入,可以查看选中的类的超类,ClassLoader以及该类的实例等信息。此外,在页面的地步,jhat还可以提供了其他查询方式。如图所示:
分析结果是以包为单位进行分组显示,分析内存漏洞主要使用其中的“Heap Histogram” 与OQL页签的功能,用Heap Histogram,找到内存中总容量最大的对象,OQL是标准的对象查询语言,类似SQL的语法对内存中对象进行查询统计,关于OQL大家感兴趣可以自行查看。
六、jstack,查看虚拟机当前线程快照命令
这个命令也是比较常用的,一致想要不要说怎么使用,犹豫了一下,还是说一下怎么使用,定位线程问题吧。
首先先写一段代码打印出当前线程名,注意行号显示,后面会通过jstack定位到第几行
把这段代码打成jar包,上传到服务器中,然后运行命令,java -jar untitled.jar
这时使用top命令查看使用cpu较高的进程
再使用top -Hp 28226 找到这个进程里使用cpu最高的线程
然后把这个线程号转换成为16进制,28236 转成16进制为
这个时候我们可以使用jstack命令了,可以直接打印出线程dump,也可以把dump存到文件,下载到本地查看,建议是下载到本地。
然后,根据之前的线程id,是6e4c,在dump文件中找到对应的线程,然后从下往上看,就可以发现我们刚才运行的方法,并且行号也显示是15号,以此就是当cpu偏高的时候,怎么使用jstack定位到哪行代码的方法。
在以上命令中jps 、jstat、jmap、jstack,都是常用的定位性能瓶颈的命令工具,希望大家灵活运用。其实还有一些可是话工具,也是比较好用的比如,Jvisualvm,Jconsole,后面的有机会再给大家验收如何使用