原创

调优-基于JDK命令行工具的监控

1、基于JDK命令行工具的监控

1.1 X参数

-Xint:解释执行
-Xcomp:第一次使用就编译成本地代码
-Xmixed:混合模式,jvm自己来决定是否编译成本地代码

查看默认的模式

java -version

java version "1.8.0_60"

Java(TM) SE Runtime Environment (build 1.8.0_60-b27)

Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)

最后的mixed mode表示相应的模式

修改(不是永久修改,应该相当于是启动参数):
java -Xint -version

1.2 XX参数

1.2.1 Boolean类型
格式: -XX:[+-] 表示启用或者禁用name属性
比如: -XX:+UseConcMarkSweepGC
-XX:UseG1GC

1.2.2 非Boolean类型
格式: -XX:= 表示name属性的值是value
比如: -XX:MaxGCPauseMills=500
-XX:GCTimeRatio=19

1.2.3 -Xms -Xmx
不是X参数,而是XX参数
-Xms等价于-XX:InitialHeapSize
-Xmx等价于-XX:MaxHeapSize

查询参数jinfo:

ps -ef | grep tomcat

查看最大内存:

jinfo -flag MaxHeapSize 15674

返回 -XX:MaxHeapSize=257949696

jinfo -flag ThreadStackSize 15674

返回 -XX:ThreadStackSize=1024 [单位应该是k]

查看垃圾回收器:

jinfo -flag UseConcMarkSweepGC 15674

返回 -XX:-UseConcMarkSweepGC

jinfo -flag UseG1GC 15674

返回 -XX:-UseG1GC

jinfo -flag UseParallelGC 15674

返回 -XX:-UseParallelGC

jinfo -flags 15674

返回已经被用户或者jvm修改后的值

Attaching to process ID 15674, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.151-b12
Non-default VM flags: -XX:CICompilerCount=3
-XX:InitialHeapSize=16777216 -XX:MaxHeapSize=257949696
-XX:MaxNewSize=85983232 -XX:MinHeapDeltaBytes=196608
-XX:NewSize=5570560 -XX:OldSize=11206656
-XX:+UseCompressedClassPointers -XX:+UseCompressedOops
-XX:+UseFastUnorderedTimeStamps
Command line: -Djava.util.logging.config.file=/usr/mylibs/tomcat7/apache-tomcat-7.0.73/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager
-Djdk.tls.ephemeralDHKeySize=2048 -Djava.endorsed.dirs=/usr/mylibs/tomcat7/apache-tomcat-7.0.73/endorsed -Dcatalina.base=/usr/mylibs/tomcat7/apache-tomcat-7.0.73
-Dcatalina.home=/usr/mylibs/tomcat7/apache-tomcat-7.0.73 -Djava.io.tmpdir=/usr/mylibs/tomcat7/apache-tomcat-7.0.73/temp

查看jvm运行时参数

-XX:+PrintFlagsInitial
-XX:+PrintFlagsFinal
-XX:+UnlockExperimentalVMOptions 解锁实验参数
-XX:+UnlockDiagnosticVMOptions 解锁诊断参数
-XX:+PrintCommandLineFlags 打印命令行参数

打印预览

bool useG1GC                   = false
bool useGCLogFileRotaion       = false
bool useGCOverheadLimit        = true

uintx InitialHeapSize          := 130023424
uintx MaxHeapSize              := 2053111808
uintx MaxNewSize               := 684195840

= 表示默认值
:= 被用户或者jvm修改后的值

用法:

调出cmd窗口,输入 java -XX:+PrintFlagsInitial -version

1.3 jps

查看当前系统运行了哪些Java进程

[root@localhost admin]# jps

1168 jenkins.war

16313 Jps

15674 Bootstrap

[root@localhost admin]# jps -l  加上参数-l显示完整的类名

1168 /usr/lib/jenkins/jenkins.war

15674 org.apache.catalina.startup.Bootstrap

16350 sun.tools.jps.Jps

https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jps.html

1.4 jstat查看jvm统计信息

类装载、垃圾收集、jit编译

jstat -help

https://docs.oracle.com/javase/8/docs/technotes/tools/unix/jstat.htm#BEHHGFAE

   jstat [ generalOption | outputOptions vmid [ interval[s|ms] [ count ] ]
   jps -l
   jstat -class 15674 1000 10

垃圾收集

-gc、-gcutil、-gccause、-gcnew、-gcold

jstat -gc 15674 1000 10
S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT
25088.0 24064.0 9309.2 0.0 103424.0 83388.8 46080.0 22434.7 32384.0 31828.3 3968.0 3794.6 14 2.781 3 0.789 3.570

avatar

jstat -compiler 1473
Compiled Failed Invalid Time FailedType FailedMethod
3775 1 0 52.82 1 org/apache/catalina/loader/WebappClassLoaderBase findResourceInternal

1.5 jmap+MAT实战内存溢出

com.jiangjiesheng.javaOptimizationAndDebug.jvm.MemoryController

修改运行参数:Edit Configuration > vm Options > -Xmx32M -Xms32M

导出内存映像文件:

  1. 内存溢出自动导出
    -XX:+HeapDumpOnOutOfMemoryError
    -XX:HeapDumpPath=./export/

    修改运行参数:Edit Configuration > vm Options > -Xmx32M -Xms32M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./

    java.lang.OutOfMemoryError: Java heap space
    Dumping heap to ./\java_pid9544.hprof ...
    Heap dump file created [45711311 bytes in 0.337 secs]

    在当前项目目录下可以看到java_pid9544.hprof文件

  2. 使用jmap命令手动导出
    jmap -help

   -dump:<dump-options> to dump java heap in hprof binary format
        dump-options:
             live         dump only live objects; if not specified,
                                       all objects in the heap are dumped.
             format=b     binary format
             file=<file>  dump heap to <file>
        Example: jmap -dump:live,format=b,file=heap.bin <pid>
jps -l
    10032 sun.tools.jps.Jps
    5908 org.jetbrains.jps.cmdline.Launcher
    5688 org.jetbrains.idea.maven.server.RemoteMavenServer
    9432
    9544 com.jiangjiesheng.javaOptimizationAndDebug.JavaOptimizationAndDebugForProdEnvApplication

    cd Desktop
    jmap -dump:format=b,file=java_pid9544_by_jmap.hprof 9544

MAT分析内存溢出:

    下载 http://www.eclipse.org/mat/downloads.php

    导入.hprof文件,显示怀疑的内存溢出位置
    可以正则看出class name(输入com.jiangjiesheng.cn 后回车)占用的内存,
    选中Objects数目特别多并且占用内存特别大的,
    右击 > Merge Shortest Paths to GC Roots > exclude all phantom/weak/soft  etc.references (只看强引用)

avatar

1.6 jstack实战死循环与死锁

[root@localhost ~]# jps -l       
1472 org.apache.catalina.startup.Bootstrap
1490 sun.tools.jps.Jps

jstack 1472 > pid1472.txt

sz pid1472.txt
top -p 1472 -H

Java线程状态:

NEW WAITING RUNNABLE TIMED_WAITING BLOCKED TERMINATED

线程介绍见 https://docs.oracle.com/javase/8/docs/technotes/guides/troubleshoot/tooldescr034.html

avatar

来源 https://mp.weixin.qq.com/s/GsxeFM7QWuR--Kbpb7At2w

1.6.1 死循环演示代码

com.jiangjiesheng.javaOptimizationAndDebug.jvm.CpuController

修改端口号12345

打包放在linux中测试

打包

mvn clean package -Dmaven.test.skip=true

上传到linux,并执行

nohup java -jar java-optimization-and-debug-for-prod-env-0.0.1-SNAPSHOT.jar &

# 查看端口
netstat -ntlp

# 外部请求失败,不能连接到虚拟主机,所以直接在虚拟主机中 
wget localhost:12345/loop

# top 命令查看java进程占用cpu100%
# 终止java任务进程
ps -ef | grep java
kill -9 xxpid
1.6.2 死锁演示代码

同样的在linux下访问

wget localhost:12345/deadlock

ps -ef | grep java
root      10892   8895 29 13:38 pts/0    00:00:53 java -jar java-optimization-and-debug-for-prod-env-0.0.1-SNAPSHOT.jar

jstack 10892 > jstack.deadlock.10892.txt
# jstack -F 10892 > jstack.deadlock.10892.txt  # -F参数可以强制导出
#下载
sz jstack.deadlock.10892.txt

# 打开并拉最后:

Found one Java-level deadlock:
=============================
"Thread-5":
  waiting to lock monitor 0x00007f1a548317f8 (object 0x00000000e463ae00, a java.lang.Object),
  which is held by "Thread-4"
"Thread-4":
  waiting to lock monitor 0x00007f1a5482f6f8 (object 0x00000000e463ae10, a java.lang.Object),
  which is held by "Thread-5"

Java stack information for the threads listed above:
===================================================
"Thread-5":
    at com.jiangjiesheng.javaOptimizationAndDebug.jvm.CpuController.lambda$deadLock$1(CpuController.java:43)
    - waiting to lock <0x00000000e463ae00> (a java.lang.Object)
    - locked <0x00000000e463ae10> (a java.lang.Object)
    at com.jiangjiesheng.javaOptimizationAndDebug.jvm.CpuController$$Lambda$367/392243588.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:748)
"Thread-4":
    at com.jiangjiesheng.javaOptimizationAndDebug.jvm.CpuController.lambda$deadLock$0(CpuController.java:31)
    - waiting to lock <0x00000000e463ae10> (a java.lang.Object)
    - locked <0x00000000e463ae00> (a java.lang.Object)
    at com.jiangjiesheng.javaOptimizationAndDebug.jvm.CpuController$$Lambda$366/1004710492.run(Unknown Source)
    at java.lang.Thread.run(Thread.java:748)

Found 1 deadlock.

综合相关文档
https://docs.oracle.com/javase/8/docs/technotes/tools/unix/index.html

jcmd、jinfo、jhat、jmap、jsadebugd、jstack

正文到此结束
本文目录