常用的Java命令行工具的使用梳理,方便以后线上问题排查处理.
示例使用的虚拟机版本(JVM自带命令行工具在bin目录下)
[root@localhost ~]# java -version java version "1.8.0_121" Java(TM) SE Runtime Environment (build 1.8.0_121-b13) Java HotSpot(TM) 64-Bit Server VM (build 25.121-b13, mixed mode) [root@localhost ~]# which java /usr/local/jdk1.8.0_121/bin/java [root@localhost ~]# ls /usr/local/jdk1.8.0_121/bin/ appletviewer jarsigner javah jcmd jhat jmc.ini jstat orbd rmiregistry unpack200 ControlPanel java javap jconsole jinfo jps jstatd pack200 schemagen wsgen extcheck javac javapackager jcontrol jjs jrunscript jvisualvm policytool serialver wsimport idlj javadoc java-rmi.cgi jdb jmap jsadebugd keytool rmic servertool xjc jar javafxpackager javaws jdeps jmc jstack native2ascii rmid tnameserv
Java虚拟机的运行时快照.将Java虚拟机运行时的状态和信息保存到文件, 用于补足传统Bug分析手段的不足,可在任何Java环境使用; 信息量充足;针对非功能正确性的Bug(像多线程幵发、内存泄漏)
配置jvm参数 -XX:+HeapDumpOnOutOfMemoryError
让虚拟机在OOM异常出现之后自动生成dump文件.
配置jvm参数 -XX:+HeapDumpOnCtrlBreak
使用Ctrl+Break键,让虚拟机生成dump文件.
使用JDK自带工具: Java VisualVM
Linux系统下通过kill -3 命令发送进程退出信号'吓唬'一下虚拟机,也能拿到dump文件.
jps(Jvm Process Status Tool) 虚拟机进程状态工具, 可以用于查看当前运行的java行程以及相关参数
[root@localhost ~]# jps -help usage: jps [-help] jps [-q] [-mlvV] [<hostid>] Definitions: <hostid>: <hostname>[:<port>]
[root@localhost ~]# jps -q 3126 6940
[root@localhost ~]# jps -l 3126 org.apache.catalina.startup.Bootstrap 6955 sun.tools.jps.Jps
[root@localhost ~]# jps -m 3126 Bootstrap start 6970 Jps -m [root@localhost ~]# jps -lm 3126 org.apache.catalina.startup.Bootstrap start 6985 sun.tools.jps.Jps -lm
[root@localhost ~]# jps -V 7011 Jps 3126 Bootstrap [root@localhost ~]# jps -lV 7026 sun.tools.jps.Jps 3126 org.apache.catalina.startup.Bootstrap
[root@localhost ~]# jps -v 7073 Jps -Dapplication.home=/usr/local/jdk1.8.0_121 -Xms8m 3126 Bootstrap -Djava.util.logging.config.file=/usr/local/confluence-6.0.3/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.tomcat.websocket.DEFAULT_BUFFER_SIZE=32768 -Xms1536m -Xmx2048m -XX:+UseG1GC -Datlassian.plugins.enable.wait=300 -Djava.awt.headless=true -XX:G1ReservePercent=20 -Xloggc:/usr/local/confluence-6.0.3/logs/gc-2017-10-15_16-08-58.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=2M -XX:-PrintGCDetails -XX:+PrintGCDateStamps -XX:-PrintTenuringDistribution -Dhttp.socket.timeout=10 -Djava.endorsed.dirs=/usr/local/confluence-6.0.3/endorsed -Dcatalina.base=/usr/local/confluence-6.0.3 -Dcatalina.home=/usr/local/confluence-6.0.3 -Djava.io.tmpdir=/usr/local/confluence-6.0.3/temp [root@localhost ~]# jps -lv 7088 sun.tools.jps.Jps -Dapplication.home=/usr/local/jdk1.8.0_121 -Xms8m 3126 org.apache.catalina.startup.Bootstrap -Djava.util.logging.config.file=/usr/local/confluence-6.0.3/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.tomcat.websocket.DEFAULT_BUFFER_SIZE=32768 -Xms1536m -Xmx2048m -XX:+UseG1GC -Datlassian.plugins.enable.wait=300 -Djava.awt.headless=true -XX:G1ReservePercent=20 -Xloggc:/usr/local/confluence-6.0.3/logs/gc-2017-10-15_16-08-58.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=2M -XX:-PrintGCDetails -XX:+PrintGCDateStamps -XX:-PrintTenuringDistribution -Dhttp.socket.timeout=10 -Djava.endorsed.dirs=/usr/local/confluence-6.0.3/endorsed -Dcatalina.base=/usr/local/confluence-6.0.3 -Dcatalina.home=/usr/local/confluence-6.0.3 -Djava.io.tmpdir=/usr/local/confluence-6.0.3/temp [root@localhost ~]# jps -lmv 3126 org.apache.catalina.startup.Bootstrap start -Djava.util.logging.config.file=/usr/local/confluence-6.0.3/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.tomcat.websocket.DEFAULT_BUFFER_SIZE=32768 -Xms1536m -Xmx2048m -XX:+UseG1GC -Datlassian.plugins.enable.wait=300 -Djava.awt.headless=true -XX:G1ReservePercent=20 -Xloggc:/usr/local/confluence-6.0.3/logs/gc-2017-10-15_16-08-58.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=2M -XX:-PrintGCDetails -XX:+PrintGCDateStamps -XX:-PrintTenuringDistribution -Dhttp.socket.timeout=10 -Djava.endorsed.dirs=/usr/local/confluence-6.0.3/endorsed -Dcatalina.base=/usr/local/confluence-6.0.3 -Dcatalina.home=/usr/local/confluence-6.0.3 -Djava.io.tmpdir=/usr/local/confluence-6.0.3/temp 7103 sun.tools.jps.Jps -lmv -Dapplication.home=/usr/local/jdk1.8.0_121 -Xms8m
jinfo(Configuration Info for Java) 作用是实时地查看和调整虚拟机各项参数.
[root@localhost ~]# jinfo -help Usage: jinfo [option] <pid> (to connect to running process) jinfo [option] <executable <core> (to connect to a core file) jinfo [option] [server_id@]<remote server IP or hostname> (to connect to remote debug server) where <option> is one of: -flag <name> to print the value of the named VM flag -flag [+|-]<name> to enable or disable the named VM flag -flag <name>=<value> to set the named VM flag to the given value -flags to print VM flags -sysprops to print Java system properties <no option> to print both of the above -h | -help to print this help message
[root@localhost ~]# jps -l 3126 org.apache.catalina.startup.Bootstrap 4076 sun.tools.jps.Jps [root@localhost ~]# jinfo 3126 Attaching to process ID 3126, please wait... Debugger attached successfully. Server compiler detected. JVM version is 25.121-b13 Java System Properties: java.vendor = Oracle Corporation sun.java.launcher = SUN_STANDARD catalina.base = /usr/local/confluence-6.0.3 sun.management.compiler = HotSpot 64-Bit Tiered Compilers catalina.useNaming = true os.name = Linux java.util.logging.config.file = /usr/local/confluence-6.0.3/conf/logging.properties sun.boot.class.path = /usr/local/jdk1.8.0_121/jre/lib/resources.jar:/usr/local/jdk1.8.0_121/jre/lib/rt.jar:/usr/local/jdk1.8.0_121/jre/lib/sunrsasign.jar:/usr/local/jdk1.8.0_121/jre/lib/jsse.jar:/usr/local/jdk1.8.0_121/jre/lib/jce.jar:/usr/local/jdk1.8.0_121/jre/lib/charsets.jar:/usr/local/jdk1.8.0_121/jre/lib/jfr.jar:/usr/local/jdk1.8.0_121/jre/classes java.vm.specification.vendor = Oracle Corporation java.runtime.version = 1.8.0_121-b13 atlassian.plugins.enable.wait = 300 user.name = root shared.loader = tomcat.util.scan.StandardJarScanFilter.jarsToScan = log4j-web*.jar,log4j-taglib*.jar,log4javascript*.jar,slf4j-taglib*.jar com.sun.jndi.ldap.connect.pool.protocol = plain ssl com.sun.jndi.ldap.connect.pool.authentication = simple tomcat.util.buf.StringCache.byte.enabled = true user.language = zh java.naming.factory.initial = org.apache.naming.java.javaURLContextFactory sun.boot.library.path = /usr/local/jdk1.8.0_121/jre/lib/amd64 atlassian.enable.spring.strong.cache.bean.metadata = true jdk.tls.ephemeralDHKeySize = 2048 java.version = 1.8.0_121 java.util.logging.manager = org.apache.juli.ClassLoaderLogManager user.timezone = Asia/Shanghai sun.arch.data.model = 64 atlassian.enable.spring.strong.cache.bean.metadata.flush = true java.endorsed.dirs = /usr/local/confluence-6.0.3/endorsed sun.cpu.isalist = sun.jnu.encoding = UTF-8 file.encoding.pkg = sun.io org.apache.tomcat.websocket.DEFAULT_BUFFER_SIZE = 32768 package.access = sun.,org.apache.catalina.,org.apache.coyote.,org.apache.jasper.,org.apache.tomcat. file.separator = / java.specification.name = Java Platform API Specification java.class.version = 52.0 user.country = CN java.home = /usr/local/jdk1.8.0_121/jre atlassian.org.osgi.framework.bootdelegation.extra = org.apache.lucene.* java.vm.info = mixed mode os.version = 3.10.0-514.6.1.el7.x86_64 com.sun.jndi.ldap.connect.pool.prefsize = 10 sun.font.fontmanager = sun.awt.X11FontManager path.separator = : java.vm.version = 25.121-b13 java.protocol.handler.pkgs = org.apache.catalina.webresources java.awt.printerjob = sun.print.PSPrinterJob sun.io.unicode.encoding = UnicodeLittle sun.java2d.opengl = true awt.toolkit = sun.awt.X11.XToolkit package.definition = sun.,java.,org.apache.catalina.,org.apache.coyote.,org.apache.jasper.,org.apache.naming.,org.apache.tomcat. java.naming.factory.url.pkgs = org.apache.naming user.home = /root java.specification.vendor = Oracle Corporation 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,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,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 java.library.path = /usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib java.vendor.url = http://java.oracle.com/ java.vm.vendor = Oracle Corporation common.loader = "${catalina.base}/lib","${catalina.base}/lib/*.jar","${catalina.home}/lib","${catalina.home}/lib/*.jar" java.runtime.name = Java(TM) SE Runtime Environment sun.java.command = org.apache.catalina.startup.Bootstrap start java.class.path = /usr/local/confluence-6.0.3/bin/bootstrap.jar:/usr/local/confluence-6.0.3/bin/tomcat-juli.jar hibernate.bytecode.use_reflection_optimizer = true com.sun.jndi.ldap.connect.pool.maxsize = 0 java.vm.specification.name = Java Virtual Machine Specification java.vm.specification.version = 1.8 catalina.home = /usr/local/confluence-6.0.3 sun.cpu.endian = little sun.os.patch.level = unknown java.awt.headless = true java.io.tmpdir = /usr/local/confluence-6.0.3/temp java.vendor.url.bug = http://bugreport.sun.com/bugreport/ server.loader = os.arch = amd64 java.awt.graphicsenv = sun.awt.X11GraphicsEnvironment java.ext.dirs = /usr/local/jdk1.8.0_121/jre/lib/ext:/usr/java/packages/lib/ext user.dir = / com.sun.jndi.ldap.connect.pool.initsize = 1 line.separator = java.vm.name = Java HotSpot(TM) 64-Bit Server VM file.encoding = UTF-8 com.sun.jndi.ldap.connect.pool.timeout = 30000 http.socket.timeout = 10 java.specification.version = 1.8 plugin.webresource.javascript.try.catch.wrapping = true VM Flags: Non-default VM flags: -XX:CICompilerCount=3 -XX:ConcGCThreads=1 -XX:G1HeapRegionSize=1048576 -XX:G1ReservePercent=20 -XX:GCLogFileSize=2097152 -XX:InitialHeapSize=1610612736 -XX:MarkStackSize=4194304 -XX:MaxHeapSize=2147483648 -XX:MaxNewSize=1287651328 -XX:MinHeapDeltaBytes=1048576 -XX:NumberOfGCLogFiles=5 -XX:+PrintGC -XX:+PrintGCDateStamps -XX:-PrintGCDetails -XX:+PrintGCTimeStamps -XX:-PrintTenuringDistribution -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseG1GC -XX:+UseGCLogFileRotation Command line: -Djava.util.logging.config.file=/usr/local/confluence-6.0.3/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.tomcat.websocket.DEFAULT_BUFFER_SIZE=32768 -Xms1536m -Xmx2048m -XX:+UseG1GC -Datlassian.plugins.enable.wait=300 -Djava.awt.headless=true -XX:G1ReservePercent=20 -Xloggc:/usr/local/confluence-6.0.3/logs/gc-2017-10-15_16-08-58.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=2M -XX:-PrintGCDetails -XX:+PrintGCDateStamps -XX:-PrintTenuringDistribution -Dhttp.socket.timeout=10 -Djava.endorsed.dirs=/usr/local/confluence-6.0.3/endorsed -Dcatalina.base=/usr/local/confluence-6.0.3 -Dcatalina.home=/usr/local/confluence-6.0.3 -Djava.io.tmpdir=/usr/local/confluence-6.0.3/temp
[root@localhost ~]# jinfo -flags 3126 Attaching to process ID 3126, please wait... Debugger attached successfully. Server compiler detected. JVM version is 25.121-b13 Non-default VM flags: -XX:CICompilerCount=3 -XX:ConcGCThreads=1 -XX:G1HeapRegionSize=1048576 -XX:G1ReservePercent=20 -XX:GCLogFileSize=2097152 -XX:InitialHeapSize=1610612736 -XX:MarkStackSize=4194304 -XX:MaxHeapSize=2147483648 -XX:MaxNewSize=1287651328 -XX:MinHeapDeltaBytes=1048576 -XX:NumberOfGCLogFiles=5 -XX:+PrintGC -XX:+PrintGCDateStamps -XX:-PrintGCDetails -XX:+PrintGCTimeStamps -XX:-PrintTenuringDistribution -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseFastUnorderedTimeStamps -XX:+UseG1GC -XX:+UseGCLogFileRotation Command line: -Djava.util.logging.config.file=/usr/local/confluence-6.0.3/conf/logging.properties -Djava.util.logging.manager=org.apache.juli.ClassLoaderLogManager -Djdk.tls.ephemeralDHKeySize=2048 -Djava.protocol.handler.pkgs=org.apache.catalina.webresources -Dorg.apache.tomcat.websocket.DEFAULT_BUFFER_SIZE=32768 -Xms1536m -Xmx2048m -XX:+UseG1GC -Datlassian.plugins.enable.wait=300 -Djava.awt.headless=true -XX:G1ReservePercent=20 -Xloggc:/usr/local/confluence-6.0.3/logs/gc-2017-10-15_16-08-58.log -XX:+UseGCLogFileRotation -XX:NumberOfGCLogFiles=5 -XX:GCLogFileSize=2M -XX:-PrintGCDetails -XX:+PrintGCDateStamps -XX:-PrintTenuringDistribution -Dhttp.socket.timeout=10 -Djava.endorsed.dirs=/usr/local/confluence-6.0.3/endorsed -Dcatalina.base=/usr/local/confluence-6.0.3 -Dcatalina.home=/usr/local/confluence-6.0.3 -Djava.io.tmpdir=/usr/local/confluence-6.0.3/temp [root@localhost ~]# [root@localhost ~]# jinfo -flag PrintGCDetails 3126 -XX:-PrintGCDetails [root@localhost ~]# jinfo -flag MaxHeapSize 3126 -XX:MaxHeapSize=2147483648
[root@localhost ~]# jinfo -sysprops 3126 Attaching to process ID 3126, please wait... Debugger attached successfully. Server compiler detected. JVM version is 25.121-b13 java.vendor = Oracle Corporation sun.java.launcher = SUN_STANDARD catalina.base = /usr/local/confluence-6.0.3 sun.management.compiler = HotSpot 64-Bit Tiered Compilers catalina.useNaming = true os.name = Linux java.util.logging.config.file = /usr/local/confluence-6.0.3/conf/logging.properties sun.boot.class.path = /usr/local/jdk1.8.0_121/jre/lib/resources.jar:/usr/local/jdk1.8.0_121/jre/lib/rt.jar:/usr/local/jdk1.8.0_121/jre/lib/sunrsasign.jar:/usr/local/jdk1.8.0_121/jre/lib/jsse.jar:/usr/local/jdk1.8.0_121/jre/lib/jce.jar:/usr/local/jdk1.8.0_121/jre/lib/charsets.jar:/usr/local/jdk1.8.0_121/jre/lib/jfr.jar:/usr/local/jdk1.8.0_121/jre/classes java.vm.specification.vendor = Oracle Corporation java.runtime.version = 1.8.0_121-b13 atlassian.plugins.enable.wait = 300 user.name = root shared.loader = tomcat.util.scan.StandardJarScanFilter.jarsToScan = log4j-web*.jar,log4j-taglib*.jar,log4javascript*.jar,slf4j-taglib*.jar com.sun.jndi.ldap.connect.pool.protocol = plain ssl com.sun.jndi.ldap.connect.pool.authentication = simple tomcat.util.buf.StringCache.byte.enabled = true user.language = zh java.naming.factory.initial = org.apache.naming.java.javaURLContextFactory sun.boot.library.path = /usr/local/jdk1.8.0_121/jre/lib/amd64 atlassian.enable.spring.strong.cache.bean.metadata = true jdk.tls.ephemeralDHKeySize = 2048 java.version = 1.8.0_121 java.util.logging.manager = org.apache.juli.ClassLoaderLogManager user.timezone = Asia/Shanghai sun.arch.data.model = 64 atlassian.enable.spring.strong.cache.bean.metadata.flush = true java.endorsed.dirs = /usr/local/confluence-6.0.3/endorsed sun.cpu.isalist = sun.jnu.encoding = UTF-8 file.encoding.pkg = sun.io org.apache.tomcat.websocket.DEFAULT_BUFFER_SIZE = 32768 package.access = sun.,org.apache.catalina.,org.apache.coyote.,org.apache.jasper.,org.apache.tomcat. file.separator = / java.specification.name = Java Platform API Specification java.class.version = 52.0 user.country = CN java.home = /usr/local/jdk1.8.0_121/jre atlassian.org.osgi.framework.bootdelegation.extra = org.apache.lucene.* java.vm.info = mixed mode os.version = 3.10.0-514.6.1.el7.x86_64 com.sun.jndi.ldap.connect.pool.prefsize = 10 sun.font.fontmanager = sun.awt.X11FontManager path.separator = : java.vm.version = 25.121-b13 java.protocol.handler.pkgs = org.apache.catalina.webresources java.awt.printerjob = sun.print.PSPrinterJob sun.io.unicode.encoding = UnicodeLittle sun.java2d.opengl = true awt.toolkit = sun.awt.X11.XToolkit package.definition = sun.,java.,org.apache.catalina.,org.apache.coyote.,org.apache.jasper.,org.apache.naming.,org.apache.tomcat. java.naming.factory.url.pkgs = org.apache.naming user.home = /root java.specification.vendor = Oracle Corporation 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,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,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 java.library.path = /usr/java/packages/lib/amd64:/usr/lib64:/lib64:/lib:/usr/lib java.vendor.url = http://java.oracle.com/ java.vm.vendor = Oracle Corporation common.loader = "${catalina.base}/lib","${catalina.base}/lib/*.jar","${catalina.home}/lib","${catalina.home}/lib/*.jar" java.runtime.name = Java(TM) SE Runtime Environment sun.java.command = org.apache.catalina.startup.Bootstrap start java.class.path = /usr/local/confluence-6.0.3/bin/bootstrap.jar:/usr/local/confluence-6.0.3/bin/tomcat-juli.jar hibernate.bytecode.use_reflection_optimizer = true com.sun.jndi.ldap.connect.pool.maxsize = 0 java.vm.specification.name = Java Virtual Machine Specification java.vm.specification.version = 1.8 catalina.home = /usr/local/confluence-6.0.3 sun.cpu.endian = little sun.os.patch.level = unknown java.awt.headless = true java.io.tmpdir = /usr/local/confluence-6.0.3/temp java.vendor.url.bug = http://bugreport.sun.com/bugreport/ server.loader = os.arch = amd64 java.awt.graphicsenv = sun.awt.X11GraphicsEnvironment java.ext.dirs = /usr/local/jdk1.8.0_121/jre/lib/ext:/usr/java/packages/lib/ext user.dir = / com.sun.jndi.ldap.connect.pool.initsize = 1 line.separator = java.vm.name = Java HotSpot(TM) 64-Bit Server VM file.encoding = UTF-8 com.sun.jndi.ldap.connect.pool.timeout = 30000 http.socket.timeout = 10 java.specification.version = 1.8 plugin.webresource.javascript.try.catch.wrapping = true
javap是jdk自带的一个工具,可以对代码反编译,也可以查看java编译器生成的字节码.
[root@localhost ~]# javap -help 用法: javap <options> <classes> 其中, 可能的选项包括: -help --help -? 输出此用法消息 -version 版本信息 -v -verbose 输出附加信息 -l 输出行号和本地变量表 -public 仅显示公共类和成员 -protected 显示受保护的/公共类和成员 -package 显示程序包/受保护的/公共类 和成员 (默认) -p -private 显示所有类和成员 -c 对代码进行反汇编 -s 输出内部类型签名 -sysinfo 显示正在处理的类的 系统信息 (路径, 大小, 日期, MD5 散列) -constants 显示最终常量 -classpath <path> 指定查找用户类文件的位置 -cp <path> 指定查找用户类文件的位置 -bootclasspath <path> 覆盖引导类文件的位置
javap命令分解一个class文件,它根据options来决定到底输出什么.如果没有使用options,那么javap将会输出包,类里的protected和public域以及类里的所有方法.javap将会把它们输出在标准输出上
[root@localhost ~]# cat ThreadDumpTest.java import java.util.concurrent.ExecutorService; import java.util.concurrent.Executors; public class ThreadDumpTest { public static void main(String[] args) { ExecutorService executor = Executors.newFixedThreadPool(3); for(int i=0; i<5; i++){ executor.submit(new ThreadPrint("测试线程"+ i)); } } static class ThreadPrint implements Runnable{ private String name; private ThreadPrint(String name){ this.name = name; } @Override public void run() { Thread thread = Thread.currentThread(); thread.setName(name); int i=0; while (true){ System.out.println(thread.getName() + "输出" + i++); } } } } [root@localhost ~]# javac ThreadDumpTest.java
[root@localhost ~]# javap ThreadDumpTest.class Compiled from "ThreadDumpTest.java" public class ThreadDumpTest { public ThreadDumpTest(); public static void main(java.lang.String[]); }
[root@localhost ~]# javap -version ThreadDumpTest.class 1.8.0_121 Compiled from "ThreadDumpTest.java" public class ThreadDumpTest { public ThreadDumpTest(); public static void main(java.lang.String[]); }
[root@localhost ~]# javap -sysinfo ThreadDumpTest.class Classfile /root/ThreadDumpTest.class Last modified 2017-10-15; size 967 bytes MD5 checksum b8dce8aa07d62201b068e47eef31fa75 Compiled from "ThreadDumpTest.java" public class ThreadDumpTest { public ThreadDumpTest(); public static void main(java.lang.String[]); }
[root@localhost ~]# javap -constants ThreadDumpTest.class Compiled from "ThreadDumpTest.java" public class ThreadDumpTest { public ThreadDumpTest(); public static void main(java.lang.String[]); }
[root@localhost ~]# javap -l ThreadDumpTest.class Compiled from "ThreadDumpTest.java" public class ThreadDumpTest { public ThreadDumpTest(); LineNumberTable: line 4: 0 public static void main(java.lang.String[]); LineNumberTable: line 8: 0 line 9: 5 line 10: 12 line 9: 46 line 12: 52 }
[root@localhost ~]# javap -c ThreadDumpTest.class Compiled from "ThreadDumpTest.java" public class ThreadDumpTest { public ThreadDumpTest(); Code: 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return public static void main(java.lang.String[]); Code: 0: iconst_3 1: invokestatic #2 // Method java/util/concurrent/Executors.newFixedThreadPool:(I)Ljava/util/concurrent/ExecutorService; 4: astore_1 5: iconst_0 6: istore_2 7: iload_2 8: iconst_5 9: if_icmpge 52 12: aload_1 13: new #3 // class ThreadDumpTest$ThreadPrint 16: dup 17: new #4 // class java/lang/StringBuilder 20: dup 21: invokespecial #5 // Method java/lang/StringBuilder."<init>":()V 24: ldc #6 // String 测试线程 26: invokevirtual #7 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 29: iload_2 30: invokevirtual #8 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; 33: invokevirtual #9 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 36: aconst_null 37: invokespecial #10 // Method ThreadDumpTest$ThreadPrint."<init>":(Ljava/lang/String;LThreadDumpTest$1;)V 40: invokeinterface #11, 2 // InterfaceMethod java/util/concurrent/ExecutorService.submit:(Ljava/lang/Runnable;)Ljava/util/concurrent/Future; 45: pop 46: iinc 2, 1 49: goto 7 52: return }
[root@localhost ~]# javap -s ThreadDumpTest.class Compiled from "ThreadDumpTest.java" public class ThreadDumpTest { public ThreadDumpTest(); descriptor: ()V public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V }
[root@localhost ~]# javap -package ThreadDumpTest.class Compiled from "ThreadDumpTest.java" public class ThreadDumpTest { public ThreadDumpTest(); public static void main(java.lang.String[]); } [root@localhost ~]# javap -public ThreadDumpTest.class Compiled from "ThreadDumpTest.java" public class ThreadDumpTest { public ThreadDumpTest(); public static void main(java.lang.String[]); } [root@localhost ~]# javap -protected ThreadDumpTest.class Compiled from "ThreadDumpTest.java" public class ThreadDumpTest { public ThreadDumpTest(); public static void main(java.lang.String[]); } [root@localhost ~]# javap -private ThreadDumpTest.class Compiled from "ThreadDumpTest.java" public class ThreadDumpTest { public ThreadDumpTest(); public static void main(java.lang.String[]); }
[root@localhost ~]# javap -v ThreadDumpTest.class Classfile /root/ThreadDumpTest.class Last modified 2017-10-15; size 967 bytes MD5 checksum b8dce8aa07d62201b068e47eef31fa75 Compiled from "ThreadDumpTest.java" public class ThreadDumpTest minor version: 0 major version: 52 flags: ACC_PUBLIC, ACC_SUPER Constant pool: #1 = Methodref #13.#27 // java/lang/Object."<init>":()V #2 = Methodref #28.#29 // java/util/concurrent/Executors.newFixedThreadPool:(I)Ljava/util/concurrent/ExecutorService; #3 = Class #30 // ThreadDumpTest$ThreadPrint #4 = Class #31 // java/lang/StringBuilder #5 = Methodref #4.#27 // java/lang/StringBuilder."<init>":()V #6 = String #32 // 测试线程 #7 = Methodref #4.#33 // java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; #8 = Methodref #4.#34 // java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; #9 = Methodref #4.#35 // java/lang/StringBuilder.toString:()Ljava/lang/String; #10 = Methodref #3.#36 // ThreadDumpTest$ThreadPrint."<init>":(Ljava/lang/String;LThreadDumpTest$1;)V #11 = InterfaceMethodref #37.#38 // java/util/concurrent/ExecutorService.submit:(Ljava/lang/Runnable;)Ljava/util/concurrent/Future; #12 = Class #39 // ThreadDumpTest #13 = Class #40 // java/lang/Object #14 = Class #41 // ThreadDumpTest$1 #15 = Utf8 InnerClasses #16 = Utf8 ThreadPrint #17 = Utf8 <init> #18 = Utf8 ()V #19 = Utf8 Code #20 = Utf8 LineNumberTable #21 = Utf8 main #22 = Utf8 ([Ljava/lang/String;)V #23 = Utf8 StackMapTable #24 = Class #42 // java/util/concurrent/ExecutorService #25 = Utf8 SourceFile #26 = Utf8 ThreadDumpTest.java #27 = NameAndType #17:#18 // "<init>":()V #28 = Class #43 // java/util/concurrent/Executors #29 = NameAndType #44:#45 // newFixedThreadPool:(I)Ljava/util/concurrent/ExecutorService; #30 = Utf8 ThreadDumpTest$ThreadPrint #31 = Utf8 java/lang/StringBuilder #32 = Utf8 测试线程 #33 = NameAndType #46:#47 // append:(Ljava/lang/String;)Ljava/lang/StringBuilder; #34 = NameAndType #46:#48 // append:(I)Ljava/lang/StringBuilder; #35 = NameAndType #49:#50 // toString:()Ljava/lang/String; #36 = NameAndType #17:#51 // "<init>":(Ljava/lang/String;LThreadDumpTest$1;)V #37 = Class #42 // java/util/concurrent/ExecutorService #38 = NameAndType #52:#53 // submit:(Ljava/lang/Runnable;)Ljava/util/concurrent/Future; #39 = Utf8 ThreadDumpTest #40 = Utf8 java/lang/Object #41 = Utf8 ThreadDumpTest$1 #42 = Utf8 java/util/concurrent/ExecutorService #43 = Utf8 java/util/concurrent/Executors #44 = Utf8 newFixedThreadPool #45 = Utf8 (I)Ljava/util/concurrent/ExecutorService; #46 = Utf8 append #47 = Utf8 (Ljava/lang/String;)Ljava/lang/StringBuilder; #48 = Utf8 (I)Ljava/lang/StringBuilder; #49 = Utf8 toString #50 = Utf8 ()Ljava/lang/String; #51 = Utf8 (Ljava/lang/String;LThreadDumpTest$1;)V #52 = Utf8 submit #53 = Utf8 (Ljava/lang/Runnable;)Ljava/util/concurrent/Future; { public ThreadDumpTest(); descriptor: ()V flags: ACC_PUBLIC Code: stack=1, locals=1, args_size=1 0: aload_0 1: invokespecial #1 // Method java/lang/Object."<init>":()V 4: return LineNumberTable: line 4: 0 public static void main(java.lang.String[]); descriptor: ([Ljava/lang/String;)V flags: ACC_PUBLIC, ACC_STATIC Code: stack=5, locals=3, args_size=1 0: iconst_3 1: invokestatic #2 // Method java/util/concurrent/Executors.newFixedThreadPool:(I)Ljava/util/concurrent/ExecutorService; 4: astore_1 5: iconst_0 6: istore_2 7: iload_2 8: iconst_5 9: if_icmpge 52 12: aload_1 13: new #3 // class ThreadDumpTest$ThreadPrint 16: dup 17: new #4 // class java/lang/StringBuilder 20: dup 21: invokespecial #5 // Method java/lang/StringBuilder."<init>":()V 24: ldc #6 // String 测试线程 26: invokevirtual #7 // Method java/lang/StringBuilder.append:(Ljava/lang/String;)Ljava/lang/StringBuilder; 29: iload_2 30: invokevirtual #8 // Method java/lang/StringBuilder.append:(I)Ljava/lang/StringBuilder; 33: invokevirtual #9 // Method java/lang/StringBuilder.toString:()Ljava/lang/String; 36: aconst_null 37: invokespecial #10 // Method ThreadDumpTest$ThreadPrint."<init>":(Ljava/lang/String;LThreadDumpTest$1;)V 40: invokeinterface #11, 2 // InterfaceMethod java/util/concurrent/ExecutorService.submit:(Ljava/lang/Runnable;)Ljava/util/concurrent/Future; 45: pop 46: iinc 2, 1 49: goto 7 52: return LineNumberTable: line 8: 0 line 9: 5 line 10: 12 line 9: 46 line 12: 52 StackMapTable: number_of_entries = 2 frame_type = 253 /* append */ offset_delta = 7 locals = [ class java/util/concurrent/ExecutorService, int ] frame_type = 250 /* chop */ offset_delta = 44 } SourceFile: "ThreadDumpTest.java" InnerClasses: static #14; //class ThreadDumpTest$1 static #16= #3 of #12; //ThreadPrint=class ThreadDumpTest$ThreadPrint of class ThreadDumpTest
jstat(JVM Statistics Monitoring Tool) 是用于监视虚拟机各种运行状态信息的命令行工具.它尅显示本地或者远程虚拟机进程中的类装载、内存、垃圾收集、JIT编译等运行数据.
[root@localhost ~]# jstat -help Usage: jstat -help|-options jstat -<option> [-t] [-h<lines>] <vmid> [<interval> [<count>]] Definitions: <option> An option reported by the -options option <vmid> Virtual Machine Identifier. A vmid takes the following form: <lvmid>[@<hostname>[:<port>]] Where <lvmid> is the local vm identifier for the target Java virtual machine, typically a process id; <hostname> is the name of the host running the target Java virtual machine; and <port> is the port number for the rmiregistry on the target host. See the jvmstat documentation for a more complete description of the Virtual Machine Identifier. <lines> Number of samples between header lines. <interval> Sampling interval. The following forms are allowed: <n>["ms"|"s"] Where <n> is an integer and the suffix specifies the units as milliseconds("ms") or seconds("s"). The default units are "ms". <count> Number of samples to take before terminating. -J<flag> Pass <flag> directly to the runtime system. [root@localhost ~]# jstat -options -class -compiler -gc -gccapacity -gccause -gcmetacapacity -gcnew -gcnewcapacity -gcold -gcoldcapacity -gcutil -printcompilation
[root@localhost ~]# jstat -gc 3126 2 5 S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT 0.0 81920.0 0.0 81920.0 566272.0 136192.0 924672.0 558080.0 224076.0 205898.7 31368.0 26476.7 36 2.526 0 0.000 2.526 0.0 81920.0 0.0 81920.0 566272.0 136192.0 924672.0 558080.0 224076.0 205898.7 31368.0 26476.7 36 2.526 0 0.000 2.526 0.0 81920.0 0.0 81920.0 566272.0 136192.0 924672.0 558080.0 224076.0 205898.7 31368.0 26476.7 36 2.526 0 0.000 2.526 0.0 81920.0 0.0 81920.0 566272.0 136192.0 924672.0 558080.0 224076.0 205898.7 31368.0 26476.7 36 2.526 0 0.000 2.526 0.0 81920.0 0.0 81920.0 566272.0 136192.0 924672.0 558080.0 224076.0 205898.7 31368.0 26476.7 36 2.526 0 0.000 2.526
[root@localhost ~]# jstat -class 3126 Loaded Bytes Unloaded Bytes Time 39652 72532.0 15 70.1 76.55
[root@localhost ~]# jstat -compiler 3126 Compiled Failed Invalid Time FailedType FailedMethod 28416 5 0 155.87 1 com/mysql/jdbc/AbandonedConnectionCleanupThread run
[root@localhost ~]# jstat -gc 3126 S0C S1C S0U S1U EC EU OC OU MC MU CCSC CCSU YGC YGCT FGC FGCT GCT 0.0 87040.0 0.0 87040.0 601088.0 286720.0 884736.0 513536.0 223820.0 205799.4 31368.0 26473.9 35 2.374 0 0.000 2.374
[root@localhost ~]# jstat -gccapacity 3126 NGCMN NGCMX NGC S0C S1C EC OGCMN OGCMX OGC OC MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC 0.0 2097152.0 688128.0 0.0 87040.0 601088.0 0.0 2097152.0 884736.0 884736.0 0.0 1241088.0 223820.0 0.0 1048576.0 31368.0 35 0
[root@localhost ~]# jstat -gcutil 3126 S0 S1 E O M CCS YGC YGCT FGC FGCT GCT 0.00 100.00 40.03 58.04 91.95 84.40 35 2.374 0 0.000 2.374 [root@localhost ~]# jstat -gccause 3126 S0 S1 E O M CCS YGC YGCT FGC FGCT GCT LGCC GCC 0.00 100.00 40.03 58.04 91.95 84.40 35 2.374 0 0.000 2.374 G1 Evacuation Pause No GC
[root@localhost ~]# jstat -gcmetacapacity 3126 MCMN MCMX MC CCSMN CCSMX CCSC YGC FGC FGCT GCT 0.0 1241088.0 223820.0 0.0 1048576.0 31368.0 35 0 0.000 2.374
[root@localhost ~]# jstat -gcnew 3126 S0C S1C S0U S1U TT MTT DSS EC EU YGC YGCT 0.0 87040.0 0.0 87040.0 15 15 43520.0 601088.0 354304.0 35 2.374 [root@localhost ~]# jstat -gcnewcapacity 3126 NGCMN NGCMX NGC S0CMX S0C S1CMX S1C ECMX EC YGC FGC 0.0 2097152.0 688128.0 0.0 0.0 2097152.0 87040.0 2097152.0 601088.0 35 0
[root@localhost ~]# jstat -gcold 3126 MC MU CCSC CCSU OC OU YGC FGC FGCT GCT 223820.0 205799.4 31368.0 26473.9 884736.0 513536.0 35 0 0.000 2.374 [root@localhost ~]# jstat -gcoldcapacity 3126 OGCMN OGCMX OGC OC YGC FGC FGCT GCT 0.0 2097152.0 884736.0 884736.0 35 0 0.000 2.374
[root@localhost ~]# jstat -printcompilation 3126 Compiled Size Type Method 28485 305 1 java/util/GregorianCalendar pinDayOfMonth [root@localhost ~]# jstat -printcompilation 3126 Compiled Size Type Method 28486 362 1 java/lang/StringCoding encode
jstack(Stack Trace for Java) 命令用于生成虚拟机当前时刻的线程快照(一般称为threaddump或者javacore文件), 线程快照就是当前虚拟机内每一条线程正在执行的方法堆栈的集合,生成线程快照的主要目的是定位线程出现长时间停顿的原因,如线程间死锁、死循环、请求外部资源导致的长时间等待等.
在实际运行中,往往一次 dump的信息,还不足以确认问题。建议产生三次 dump信息,如果每次 dump都指向同一个问题,我们才确定问题的典型性。
[root@localhost ~]# jstack -help Usage: jstack [-l] <pid> (to connect to running process) jstack -F [-m] [-l] <pid> (to connect to a hung process) jstack [-m] [-l] <executable> <core> (to connect to a core file) jstack [-m] [-l] [server_id@]<remote server IP or hostname> (to connect to a remote debug server) Options: -F to force a thread dump. Use when jstack <pid> does not respond (process is hung) -m to print both java and native frames (mixed mode) -l long listing. Prints additional information about locks -h or -help to print this help message
[root@localhost ~]# jstack -l 3126 2017-10-15 20:16:00 Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.121-b13 mixed mode): "Attach Listener" #171 daemon prio=9 os_prio=0 tid=0x00007feab0561800 nid=0x10d4 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE Locked ownable synchronizers: - None "lucene-tracked-searchers-pruner-pool-19-thread-1" #170 prio=5 os_prio=0 tid=0x00007feac483d000 nid=0xdb9 waiting on condition [0x00007fea64670000] java.lang.Thread.State: TIMED_WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for <0x000000009794bb68> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:215) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos(AbstractQueuedSynchronizer.java:2078) at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:1093) at java.util.concurrent.ScheduledThreadPoolExecutor$DelayedWorkQueue.take(ScheduledThreadPoolExecutor.java:809) at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) Locked ownable synchronizers: - None "SupportHealthCheckThread-8" #169 daemon prio=5 os_prio=0 tid=0x00007feaa03cc800 nid=0xdb8 waiting on condition [0x00007fea63b65000] java.lang.Thread.State: WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for <0x000000008dc7bc18> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.park(LockSupport.java:175) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.await(AbstractQueuedSynchronizer.java:2039) at java.util.concurrent.LinkedBlockingQueue.take(LinkedBlockingQueue.java:442) at java.util.concurrent.ThreadPoolExecutor.getTask(ThreadPoolExecutor.java:1067) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1127) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) Locked ownable synchronizers: - None
示例展示使用Jstack查看CPU导致CPU使用率过高的问题代码
[root@localhost ~]# top top - 21:06:30 up 4:58, 3 users, load average: 0.59, 0.17, 0.09 Tasks: 185 total, 3 running, 182 sleeping, 0 stopped, 0 zombie %Cpu(s): 11.7 us, 27.6 sy, 0.0 ni, 60.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st KiB Mem : 7874196 total, 6227236 free, 855436 used, 791524 buff/cache KiB Swap: 8126460 total, 8126460 free, 0 used. 6712744 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 13176 root 20 0 4643776 60552 11976 S 83.3 0.8 0:14.11 java 13047 root 20 0 151508 6856 3972 R 77.8 0.1 0:52.33 sshd 320 root 20 0 0 0 0 S 38.9 0.0 0:01.67 kworker/1:2 792 root 20 0 4368 588 496 S 5.6 0.0 0:02.37 rngd 13202 root 20 0 157708 2300 1564 R 5.6 0.0 0:00.11 top 1 root 20 0 128092 6700 3948 S 0.0 0.1 0:01.97 systemd 2 root 20 0 0 0 0 S 0.0 0.0 0:00.01 kthreadd 3 root 20 0 0 0 0 S 0.0 0.0 0:00.02 ksoftirqd/0 5 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/0:0H 7 root rt 0 0 0 0 S 0.0 0.0 0:00.01 migration/0 8 root 20 0 0 0 0 S 0.0 0.0 0:00.00 rcu_bh 9 root 20 0 0 0 0 S 0.0 0.0 0:13.28 rcu_sched 10 root rt 0 0 0 0 S 0.0 0.0 0:00.08 watchdog/0 11 root rt 0 0 0 0 S 0.0 0.0 0:00.08 watchdog/1 12 root rt 0 0 0 0 S 0.0 0.0 0:00.02 migration/1 13 root 20 0 0 0 0 S 0.0 0.0 0:00.10 ksoftirqd/1 15 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/1:0H 16 root rt 0 0 0 0 S 0.0 0.0 0:00.08 watchdog/2 17 root rt 0 0 0 0 S 0.0 0.0 0:00.01 migration/2 18 root 20 0 0 0 0 S 0.0 0.0 0:00.16 ksoftirqd/2 20 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/2:0H 21 root rt 0 0 0 0 S 0.0 0.0 0:00.08 watchdog/3 22 root rt 0 0 0 0 S 0.0 0.0 0:00.01 migration/3 23 root 20 0 0 0 0 S 0.0 0.0 0:00.14 ksoftirqd/3 25 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kworker/3:0H 27 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 khelper 28 root 20 0 0 0 0 S 0.0 0.0 0:00.00 kdevtmpfs 29 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 netns 30 root 20 0 0 0 0 S 0.0 0.0 0:00.01 khungtaskd 31 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 writeback 32 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kintegrityd 33 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 bioset 34 root 0 -20 0 0 0 S 0.0 0.0 0:00.00 kblockd [root@localhost ~]# jps -lv 13176 ThreadDumpTest 13230 sun.tools.jps.Jps -Dapplication.home=/usr/local/jdk1.8.0_121 -Xms8m
上面可以看到CPU使用率比较高的进程为13176, 可以定位CPU使用率过高的进程主类为 ThreadDumpTest
[root@localhost ~]# top Hp 13176 top - 21:11:05 up 5:02, 3 users, load average: 0.92, 0.49, 0.23 Threads: 19 total, 2 running, 17 sleeping, 0 stopped, 0 zombie %Cpu(s): 10.6 us, 26.7 sy, 0.0 ni, 62.6 id, 0.0 wa, 0.0 hi, 0.1 si, 0.0 st KiB Mem : 7874196 total, 6228368 free, 854004 used, 791824 buff/cache KiB Swap: 8126460 total, 8126460 free, 0 used. 6713884 avail Mem PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND 13193 root 20 0 4710340 61008 11976 R 34.7 0.8 0:16.40 java 13191 root 20 0 4710340 61008 11976 R 27.3 0.8 0:20.71 java 13192 root 20 0 4710340 61008 11976 S 14.0 0.8 0:19.79 java 13176 root 20 0 4710340 61008 11976 S 0.0 0.8 0:00.00 java 13177 root 20 0 4710340 61008 11976 S 0.0 0.8 0:00.04 java 13178 root 20 0 4710340 61008 11976 S 0.0 0.8 0:00.01 java 13179 root 20 0 4710340 61008 11976 S 0.0 0.8 0:00.02 java 13180 root 20 0 4710340 61008 11976 S 0.0 0.8 0:00.02 java 13181 root 20 0 4710340 61008 11976 S 0.0 0.8 0:00.02 java 13182 root 20 0 4710340 61008 11976 S 0.0 0.8 0:00.01 java 13183 root 20 0 4710340 61008 11976 S 0.0 0.8 0:00.00 java 13184 root 20 0 4710340 61008 11976 S 0.0 0.8 0:00.00 java 13185 root 20 0 4710340 61008 11976 S 0.0 0.8 0:00.00 java 13186 root 20 0 4710340 61008 11976 S 0.0 0.8 0:00.13 java 13187 root 20 0 4710340 61008 11976 S 0.0 0.8 0:00.10 java 13188 root 20 0 4710340 61008 11976 S 0.0 0.8 0:00.02 java 13189 root 20 0 4710340 61008 11976 S 0.0 0.8 0:00.00 java 13190 root 20 0 4710340 61008 11976 S 0.0 0.8 0:00.03 java 13290 root 20 0 4710340 61008 11976 S 0.0 0.8 0:00.00 java
图中可以看到进程13176中线程13197使用CPU率最高(13191、13192其次)
[root@localhost ~]# printf "%x/n" 13193 3389 [root@localhost ~]# printf "%x/n" 13191 3387 [root@localhost ~]# printf "%x/n" 13192 3388
[root@localhost ~]# jstack -l 13176 2017-10-15 21:11:23 Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.121-b13 mixed mode): "Attach Listener" #13 daemon prio=9 os_prio=0 tid=0x00007f94ac001000 nid=0x33ea waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE Locked ownable synchronizers: - None "DestroyJavaVM" #12 prio=5 os_prio=0 tid=0x00007f94ec008800 nid=0x3379 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE Locked ownable synchronizers: - None "测试线程2" #11 prio=5 os_prio=0 tid=0x00007f94ec0f8800 nid=0x3389 waiting for monitor entry [0x00007f94cf3f2000] java.lang.Thread.State: BLOCKED (on object monitor) at java.io.PrintStream.println(PrintStream.java:805) - waiting to lock <0x0000000087c06a90> (a java.io.PrintStream) at ThreadDumpTest$ThreadPrint.run(ThreadDumpTest.java:28) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) Locked ownable synchronizers: - <0x0000000087c06c30> (a java.util.concurrent.ThreadPoolExecutor$Worker) "测试线程1" #10 prio=5 os_prio=0 tid=0x00007f94ec0f7000 nid=0x3388 waiting for monitor entry [0x00007f94cf4f3000] java.lang.Thread.State: BLOCKED (on object monitor) at java.io.PrintStream.println(PrintStream.java:805) - waiting to lock <0x0000000087c06a90> (a java.io.PrintStream) at ThreadDumpTest$ThreadPrint.run(ThreadDumpTest.java:28) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) Locked ownable synchronizers: - <0x0000000087c06f98> (a java.util.concurrent.ThreadPoolExecutor$Worker) "测试线程0" #9 prio=5 os_prio=0 tid=0x00007f94ec0f5000 nid=0x3387 runnable [0x00007f94cf5f4000] java.lang.Thread.State: RUNNABLE at java.io.FileOutputStream.writeBytes(Native Method) at java.io.FileOutputStream.write(FileOutputStream.java:326) at java.io.BufferedOutputStream.flushBuffer(BufferedOutputStream.java:82) at java.io.BufferedOutputStream.flush(BufferedOutputStream.java:140) - locked <0x0000000087c21ca0> (a java.io.BufferedOutputStream) at java.io.PrintStream.write(PrintStream.java:482) - locked <0x0000000087c06a90> (a java.io.PrintStream) at sun.nio.cs.StreamEncoder.writeBytes(StreamEncoder.java:221) at sun.nio.cs.StreamEncoder.implFlushBuffer(StreamEncoder.java:291) at sun.nio.cs.StreamEncoder.flushBuffer(StreamEncoder.java:104) - locked <0x0000000087c081a0> (a java.io.OutputStreamWriter) at java.io.OutputStreamWriter.flushBuffer(OutputStreamWriter.java:185) at java.io.PrintStream.newLine(PrintStream.java:546) - eliminated <0x0000000087c06a90> (a java.io.PrintStream) at java.io.PrintStream.println(PrintStream.java:807) - locked <0x0000000087c06a90> (a java.io.PrintStream) at ThreadDumpTest$ThreadPrint.run(ThreadDumpTest.java:28) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) Locked ownable synchronizers: - <0x0000000087c0e1c0> (a java.util.concurrent.ThreadPoolExecutor$Worker) "Service Thread" #8 daemon prio=9 os_prio=0 tid=0x00007f94ec0d9800 nid=0x3385 runnable [0x0000000000000000] java.lang.Thread.State: RUNNABLE Locked ownable synchronizers: - None "C1 CompilerThread2" #7 daemon prio=9 os_prio=0 tid=0x00007f94ec0bc000 nid=0x3384 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE Locked ownable synchronizers: - None "C2 CompilerThread1" #6 daemon prio=9 os_prio=0 tid=0x00007f94ec0ba800 nid=0x3383 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE Locked ownable synchronizers: - None "C2 CompilerThread0" #5 daemon prio=9 os_prio=0 tid=0x00007f94ec0b7800 nid=0x3382 waiting on condition [0x0000000000000000] java.lang.Thread.State: RUNNABLE Locked ownable synchronizers: - None "Signal Dispatcher" #4 daemon prio=9 os_prio=0 tid=0x00007f94ec0b6000 nid=0x3381 runnable [0x0000000000000000] java.lang.Thread.State: RUNNABLE Locked ownable synchronizers: - None "Finalizer" #3 daemon prio=8 os_prio=0 tid=0x00007f94ec083000 nid=0x3380 in Object.wait() [0x00007f94cfcfb000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x0000000087c0e4e8> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:143) - locked <0x0000000087c0e4e8> (a java.lang.ref.ReferenceQueue$Lock) at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:164) at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:209) Locked ownable synchronizers: - None "Reference Handler" #2 daemon prio=10 os_prio=0 tid=0x00007f94ec07e800 nid=0x337f in Object.wait() [0x00007f94cfdfc000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) - waiting on <0x0000000087c10768> (a java.lang.ref.Reference$Lock) at java.lang.Object.wait(Object.java:502) at java.lang.ref.Reference.tryHandlePending(Reference.java:191) - locked <0x0000000087c10768> (a java.lang.ref.Reference$Lock) at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:153) Locked ownable synchronizers: - None "VM Thread" os_prio=0 tid=0x00007f94ec076800 nid=0x337e runnable "GC task thread#0 (ParallelGC)" os_prio=0 tid=0x00007f94ec01d800 nid=0x337a runnable "GC task thread#1 (ParallelGC)" os_prio=0 tid=0x00007f94ec01f800 nid=0x337b runnable "GC task thread#2 (ParallelGC)" os_prio=0 tid=0x00007f94ec021000 nid=0x337c runnable "GC task thread#3 (ParallelGC)" os_prio=0 tid=0x00007f94ec023000 nid=0x337d runnable "VM Periodic Task Thread" os_prio=0 tid=0x00007f94ec0dc800 nid=0x3386 waiting on condition JNI global references: 11
上面步骤中进程内高CPU线程对应的16进制分表为 0x3389
、 0x3397
、 0x3388
,
分析线程快照可以看到分别对应快照中的 nid=0x3389
、 nid=0x3397
、 nid=0x3388
线程,
发现问题代码 ThreadDumpTest$ThreadPrint.run(ThreadDumpTest.java:28)
上面高CPU线程指向的问题代码如下:
"测试线程2" #11 prio=5 os_prio=0 tid=0x00007f94ec0f8800 nid=0x3389 waiting for monitor entry [0x00007f94cf3f2000] java.lang.Thread.State: BLOCKED (on object monitor) at java.io.PrintStream.println(PrintStream.java:805) - waiting to lock <0x0000000087c06a90> (a java.io.PrintStream) at ThreadDumpTest$ThreadPrint.run(ThreadDumpTest.java:28) at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) at java.util.concurrent.FutureTask.run(FutureTask.java:266) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) at java.lang.Thread.run(Thread.java:745) Locked ownable synchronizers: - <0x0000000087c06c30> (a java.util.concurrent.ThreadPoolExecutor$Worker)
查看我们的问题示例代码
[root@localhost ~]# cat ThreadDumpTest.java -n 1 import java.util.concurrent.ExecutorService; 2 import java.util.concurrent.Executors; 3 4 public class ThreadDumpTest { 5 6 public static void main(String[] args) { 7 8 ExecutorService executor = Executors.newFixedThreadPool(3); 9 for(int i=0; i<5; i++){ 10 executor.submit(new ThreadPrint("测试线程"+ i)); 11 } 12 } 13 14 static class ThreadPrint implements Runnable{ 15 16 private String name; 17 18 private ThreadPrint(String name){ 19 this.name = name; 20 } 21 22 @Override 23 public void run() { 24 Thread thread = Thread.currentThread(); 25 thread.setName(name); 26 int i=0; 27 while (true){ 28 System.out.println(thread.getName() + "输出" + i++); 29 } 30 } 31 } 32 33 } [root@localhost ~]#
死循环输出导致CPU使用率过高.
虚拟机执行Full GC时,会阻塞所有的用户线程。因此,即时获取到同步锁的线程也有可能被阻塞。 在查看线程Dump时,首先查看内存使用情况。
通过jstack命令查看线程堆栈信息时可能会看到的线程的几种状态
jmap(Java Memory Map) 用户生成堆转储快照(HeapDump), jmap的作用不仅仅是为了获取HeapDump文件, 它还可以查询finalize执行队列、Java堆和永久待的详细信息, 如空间使用率、当前用的是哪种收集器等.
说明
HeapDump是反应Java堆使用情况的内存镜像;其中主要包括系统信息、虚拟机属性、完整的线程Dump、所有类和对象的状态等.
[root@localhost ~]# jmap -help Usage: jmap [option] <pid> (to connect to running process) jmap [option] <executable <core> (to connect to a core file) jmap [option] [server_id@]<remote server IP or hostname> (to connect to remote debug server) where <option> is one of: <none> to print same info as Solaris pmap -heap to print java heap summary -histo[:live] to print histogram of java object heap; if the "live" suboption is specified, only count live objects -clstats to print class loader statistics -finalizerinfo to print information on objects awaiting finalization -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> -F force. Use with -dump:<dump-options> <pid> or -histo to force a heap dump or histogram when <pid> does not respond. The "live" suboption is not supported in this mode. -h | -help to print this help message -J<flag> to pass <flag> directly to the runtime system
[root@localhost ~]# jmap -heap 15051 Attaching to process ID 15051, please wait... Debugger attached successfully. Server compiler detected. JVM version is 25.121-b13 using thread-local object allocation. Parallel GC with 4 thread(s) Heap Configuration: MinHeapFreeRatio = 0 MaxHeapFreeRatio = 100 MaxHeapSize = 2017460224 (1924.0MB) NewSize = 42467328 (40.5MB) MaxNewSize = 672137216 (641.0MB) OldSize = 85458944 (81.5MB) NewRatio = 2 SurvivorRatio = 8 MetaspaceSize = 21807104 (20.796875MB) CompressedClassSpaceSize = 1073741824 (1024.0MB) MaxMetaspaceSize = 17592186044415 MB G1HeapRegionSize = 0 (0.0MB) Heap Usage: PS Young Generation Eden Space: capacity = 546832384 (521.5MB) used = 111311816 (106.15522003173828MB) free = 435520568 (415.3447799682617MB) 20.355746890074453% used From Space: capacity = 59768832 (57.0MB) used = 40423064 (38.550437927246094MB) free = 19345768 (18.449562072753906MB) 67.63234724078262% used To Space: capacity = 62390272 (59.5MB) used = 0 (0.0MB) free = 62390272 (59.5MB) 0.0% used PS Old Generation capacity = 170393600 (162.5MB) used = 68197144 (65.0378646850586MB) free = 102196456 (97.4621353149414MB) 40.02330134465144% used 31756 interned Strings occupying 3488392 bytes.
Parallel GC with 4 thread(s): 说明使用的GC为Parallel GC
Heap Configuration: 堆内存初始化配置
Heap Usage: 堆内存使用情况
jmap -histo 输出堆中对象统计信息(示例截取部分输出)
[root@localhost ~]# jmap -histo 15051 num #instances #bytes class name ---------------------------------------------- 1: 500577 126716152 [C 2: 26232 65237120 [B 3: 14504 35776824 [I 4: 383664 9207936 java.lang.String 5: 64455 5672040 java.lang.reflect.Method 6: 51405 4934880 java.util.jar.JarFile$JarFileEntry 7: 97535 3287848 [Ljava.lang.Object; 8: 98414 3149248 java.util.HashMap$Node 9: 72032 2305024 java.util.concurrent.ConcurrentHashMap$Node 10: 25440 1831680 java.lang.reflect.Field 11: 14102 1742584 [Ljava.util.HashMap$Node; 12: 68096 1489240 [Ljava.lang.Class; 13: 25091 1216184 [Ljava.lang.String; 14: 10460 1183000 java.lang.Class 15: 24437 1172976 org.aspectj.weaver.reflect.ShadowMatchImpl 16: 2040 1094240 [Ljava.util.concurrent.ConcurrentHashMap$Node; 17: 31998 1023936 org.apache.ibatis.reflection.property.PropertyTokenizer 18: 17825 998200 java.util.LinkedHashMap 19: 13505 864320 java.net.URL 20: 19868 794720 java.util.LinkedHashMap$Entry 21: 24437 781984 org.aspectj.weaver.patterns.ExposedState 22: 22626 724032 java.lang.ref.WeakReference 23: 14512 696576 java.nio.HeapByteBuffer 24: 14483 695184 java.nio.HeapCharBuffer 25: 21682 693824 java.util.Hashtable$Entry 26: 27121 650904 java.util.ArrayList 27: 26287 630888 java.lang.StringBuilder 28: 13050 626400 java.util.HashMap 29: 11340 453600 com.google.common.collect.AbstractMapBasedMultimap$WrappedSet 30: 11340 453600 com.google.common.collect.LinkedHashMultimap$ValueSet 31: 8848 424704 org.apache.catalina.loader.ResourceEntry 32: 10057 402280 java.util.TreeMap$Entry 33: 17013 400008 [Ljava.lang.reflect.Type; 34: 4850 388000 java.lang.reflect.Constructor 35: 11918 381376 java.lang.StackTraceElement 36: 1219 344448 [Ljava.util.Hashtable$Entry; 37: 3921 332080 [Ljava.lang.reflect.Method; 38: 8123 324920 java.lang.ref.Finalizer 39: 8047 321880 java.lang.ref.SoftReference
说明
jmap -histo:live 这个命令执行,JVM会先触发gc,然后再统计信息.
这个命令执行,JVM会将整个heap的信息dump写入到一个文件,heap如果比较大的话,就会导致这个过程比较耗时,并且执行的过程中为了保证dump的信息是可靠的,所以会暂停应用.
[root@localhost ~]# jmap -dump:format=b,file=heapDump 15051 Dumping heap to /root/heapDump ... Heap dump file created [root@localhost ~]# jhat -port 8899 heapDump Reading from heapDump... Dump file created Sun Oct 15 23:10:28 CST 2017 Snapshot read, resolving... Resolving 2737044 objects... Chasing references, expect 547 dots................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................... Eliminating duplicate references................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................... Snapshot resolved. Started HTTP server on port 8899 Server is ready.
浏览器访问: http://ip:8899/
jhat(JVM Heap Analysis Tool) 命令与jmap搭配使用, 用来分析jmap生成的堆转储快照, jhat内置了一个微型的HTTP/HTML服务器, 方便在浏览器中查看jmap生成的HeadpDump文件.
[root@localhost ~]# jhat -help Usage: jhat [-stack <bool>] [-refs <bool>] [-port <port>] [-baseline <file>] [-debug <int>] [-version] [-h|-help] <file> -J<flag> Pass <flag> directly to the runtime system. For example, -J-mx512m to use a maximum heap size of 512MB -stack false: Turn off tracking object allocation call stack. -refs false: Turn off tracking of references to objects -port <port>: Set the port for the HTTP server. Defaults to 7000 -exclude <file>: Specify a file that lists data members that should be excluded from the reachableFrom query. -baseline <file>: Specify a baseline object dump. Objects in both heap dumps with the same ID and same class will be marked as not being "new". -debug <int>: Set debug level. 0: No debug output 1: Debug hprof file parsing 2: Debug hprof file parsing, no server -version Report version number -h|-help Print this help and exit <file> The file to read For a dump file that contains multiple heap dumps, you may specify which dump in the file by appending "#<number>" to the file name, i.e. "foo.hprof#3". All boolean options default to "true"
[root@localhost ~]# jmap -dump:format=b,file=heapDump 15051 Dumping heap to /root/heapDump ... Heap dump file created [root@localhost ~]# jhat -port 8899 heapDump Reading from heapDump... Dump file created Sun Oct 15 23:10:28 CST 2017 Snapshot read, resolving... Resolving 2737044 objects... Chasing references, expect 547 dots................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................... Eliminating duplicate references................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................................... Snapshot resolved. Started HTTP server on port 8899 Server is ready.
示例机器ip地址: 192.168.0.107, 所以只需要访问http://192.168.0.107:8899即可, 一般查看堆异常情况主要看这个两各部分
具体排查时需要结合代码,观察是否大量应该被回收的对象在一直被引用或者是否有占用内存特别大的对象无法被回收.
OQL语句的执行页面: http://ip :端口/oql/
OQL帮助信息页面为: http://ip :端口/oqlhelp/
喜欢我就关注我吧!! 微信公众号:异次猿
qrcode_for_gh_1d2af15793b2_430.jpg