Java經常使用命令行工具

經常使用的Java命令行工具的使用梳理,方便之後線上問題排查處理.javascript

 

示例使用的虛擬機版本(JVM自帶命令行工具在bin目錄下)html

[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

  • javap : java字節碼信息查看工具
  • jps : java虛擬機進程信息工具
  • jinfo : java虛擬機進程配置信息工具
  • jstat : java虛擬機進程統計信息監控工具
  • jstack : java虛擬機進程堆棧跟蹤工具, 製做線程Dump
  • jmap : java虛擬機進程堆內存映射,製做堆Dump
  • jhat : java虛擬機堆轉儲快照分析工具
  • jconsole : 用於提供JVM活動的圖形化視圖,包括線程的使用、類的使用和GC活動.
  • jvisualvm: 監控JVM的GUI工具,可用來剖析運行的應用,分析JVM堆轉儲.

術語認知

Java Dump介紹

Java虛擬機的運行時快照.將Java虛擬機運行時的狀態和信息保存到文件, 用於補足傳統Bug分析手段的不足,可在任何Java環境使用; 信息量充足;針對非功能正確性的Bug(像多線程幵發、內存泄漏)mysql

  • ThreadDump : 包含全部線程的運行狀態.純文本格式
  • HeapDump: 包含線程Dump,幵包含全部堆對象的狀態,二進制格式.

製做Java Dump

使用Java虛擬機配置

配置jvm參數 -XX:+HeapDumpOnOutOfMemoryError 讓虛擬機在OOM異常出現以後自動生成dump文件.
配置jvm參數 -XX:+HeapDumpOnCtrlBreak 使用Ctrl+Break鍵,讓虛擬機生成dump文件.ios

使用圖形化工具

使用JDK自帶工具: Java VisualVMc++

Linux系統下經過kill命令

Linux系統下經過kill -3 命令發送進程退出信號'嚇唬'一下虛擬機,也能拿到dump文件.web

使用Java命令行工具
  • jstack:打印線程的棧信息,製做線程Dump.
  • jmap:打印內存映射,製做堆Dump.

命令行工具-jps

jps(Jvm Process Status Tool) 虛擬機進程狀態工具, 能夠用於查看當前運行的java行程以及相關參數spring

jps語法

[root@localhost ~]# jps -help usage: jps [-help] jps [-q] [-mlvV] [<hostid>] Definitions: <hostid>: <hostname>[:<port>] 

參數說明sql

  • -q : 忽略輸出的類名、Jar名以及傳遞給main方法的參數,只輸出pid
  • -m : 輸出虛擬機進程啓動時傳遞給主類main()方法的參數
  • -l : 輸出主類完整的包名和類名,若是進程執行的是jar包,輸出jar包路徑
  • -v : 輸出虛擬機進程啓動時jvm參數
  • -V : 輸出經過標記的文件傳遞給JVM的參數(.hotspotrc文件,或者是經過參數-XX:Flags=指定的文件)

jps示例

輸出Java進程pid
[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 
輸出經過標記文件傳遞給Jvm的參數
[root@localhost ~]# jps -V 7011 Jps 3126 Bootstrap [root@localhost ~]# jps -lV 7026 sun.tools.jps.Jps 3126 org.apache.catalina.startup.Bootstrap 
輸出進程啓動時的jvm參數
[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

jinfo(Configuration Info for Java) 做用是實時地查看和調整虛擬機各項參數.apache

jinfo語法

[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 

jinfo示例

獲取應用進程全部配置信息
[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 
打印應用進程的系統參數信息(System.getProperties())
[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

javap是jdk自帶的一個工具,能夠對代碼反編譯,也能夠查看java編譯器生成的字節碼.

javap語法

[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示例

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 
javap
[root@localhost ~]# javap ThreadDumpTest.class Compiled from "ThreadDumpTest.java" public class ThreadDumpTest { public ThreadDumpTest(); public static void main(java.lang.String[]); } 
-version
[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[]); } 
-sysinfo
[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[]); } 
-constants
[root@localhost ~]# javap -constants ThreadDumpTest.class Compiled from "ThreadDumpTest.java" public class ThreadDumpTest { public ThreadDumpTest(); public static void main(java.lang.String[]); } 
-l
[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 } 
-c
[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 } 
-s
[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 } 
-package & -public & -protected & -private
[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[]); } 
-v
[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

jstat(JVM Statistics Monitoring Tool) 是用於監視虛擬機各類運行狀態信息的命令行工具.它尅顯示本地或者遠程虛擬機進程中的類裝載、內存、垃圾收集、JIT編譯等運行數據.

jstat語法

[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 

參數說明

  • -class : 監視類裝載、卸載數量、總空間以及類裝載所耗費的時間.
  • -compiler : 顯示編譯器編譯過的方法、耗時等信息.
  • -gc : 顯示Java堆情況、包括Eden區、兩個survivor區、老年代、永久代等的容量、已用空間、GC次數以及時間等信息.
  • -gccapacity: 顯示VM內存中三代(young,old,perm)對象的使用和佔用大小
  • -gcutil : gc統計信息, 輸出主要關注已使用空間佔總弓箭的百分比
  • -gccause : 與-gcutil基本相同, 會額外輸出致使上一次GC產生的緣由
  • -gcnew : 顯示新生代GC情況
  • -gcnewcapacity : 顯示內容與-gcnew相同,輸出主要關注使用到的最大最小空間
  • -gcold : 顯示老年代GC情況
  • -gcoldcapacity : 顯示內容與-gcold相同,輸出主要關注使用到的最大最小空間
  • -printcompilation : 當前vm執行的信息

jstat示例說明

每2s執行一次查詢統計,執行5次gc統計輸出
[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 
-class
[root@localhost ~]# jstat -class 3126 Loaded Bytes Unloaded Bytes Time 39652 72532.0 15 70.1 76.55 
-compiler
[root@localhost ~]# jstat -compiler 3126 Compiled Failed Invalid Time FailedType FailedMethod 28416 5 0 155.87 1 com/mysql/jdbc/AbandonedConnectionCleanupThread run 
-gc
[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 
-gccapacity
[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 
-gcutil & -gccause
[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 

參數說明

  • S0: 新生代中Survivor space 0區已使用空間的百分比
  • S1: 新生代中Survivor space 1區已使用空間的百分比
  • E: 新生代已使用空間的百分比
  • O: 老年代已使用空間的百分比
  • P: 永久帶已使用空間的百分比
  • YGC: 從應用程序啓動到當前,發生Yang GC 的次數
  • YGCT: 從應用程序啓動到當前,Yang GC所用的時間【單位秒】
  • FGC: 從應用程序啓動到當前,發生Full GC的次數
  • FGCT: 從應用程序啓動到當前,Full GC所用的時間
  • GCT: 從應用程序啓動到當前,用於垃圾回收的總時間【單位秒】
-gcmetacapacity
[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 
-gcnew & -gcnewcapacity
[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 
-gcold & -gcoldcapacity
[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 

-printcompilation

[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

jstack(Stack Trace for Java) 命令用於生成虛擬機當前時刻的線程快照(通常稱爲threaddump或者javacore文件), 線程快照就是當前虛擬機內每一條線程正在執行的方法堆棧的集合,生成線程快照的主要目的是定位線程出現長時間停頓的緣由,如線程間死鎖、死循環、請求外部資源致使的長時間等待等.
在實際運行中,每每一次 dump的信息,還不足以確認問題。建議產生三次 dump信息,若是每次 dump都指向同一個問題,咱們才肯定問題的典型性。

jstack語法

[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 

參數說明

  • _F : 當正常輸出的請求不被響應時,強制輸出線程堆棧
  • -l : 長列表,打印關於鎖的附加信息
  • -m : 打印java和native方法(c/c++)的堆棧信息

jstack示例

使用jstack查看線程堆棧
[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分析問題代碼

示例展現使用Jstack查看CPU致使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率最高(1319一、13192其次)

將線程號(十進制)轉換後的16進制
[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進制分表爲0x33890x33970x3388,
分析線程快照能夠看到分別對應快照中的nid=0x3389nid=0x3397nid=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命令查看線程堆棧信息時可能會看到的線程的幾種狀態

  • NEW : 未啓動的。不會出如今Dump中。
  • RUNNABLE : 在虛擬機內執行的。
  • BLOCKED : 受阻塞並等待監視器鎖。
  • WATING : 無限期等待另外一個線程執行特定操做。
  • TIMED_WATING : 有時限的等待另外一個線程的特定操做。
  • TERMINATED : 已退出的。

命令行工具-Jmap

jmap(Java Memory Map) 用戶生成堆轉儲快照(HeapDump), jmap的做用不只僅是爲了獲取HeapDump文件, 它還能夠查詢finalize執行隊列、Java堆和永久待的詳細信息, 如空間使用率、當前用的是哪一種收集器等.

說明
HeapDump是反應Java堆使用狀況的內存鏡像;其中主要包括系統信息、虛擬機屬性、完整的線程Dump、全部類和對象的狀態等.

jmap語法

[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 

參數說明

  • -heap : 顯示Java堆詳細信息,如使用哪一種回收機,參數配置,分代情況等.只在Linux/Solaris平臺下有效
  • -histo : 顯示堆中對象統計信息, 包括類、示例梳理、合計容量
  • -finalizerinfo : 打印等待終結的對象信息
  • -dump : 以hprof二進制格式轉儲Java堆到指定filename的文件中,live子選項是可選的, 若是指定了live子選項,堆中只有活動的對象會被轉儲.想要瀏覽heap dump,你可使用jhat(Java堆分析工具)讀取生成的文件.
  • -F : 強制模式.若是指定的pid沒有響應,請使用jmap -dump或jmap -histo選項.
  • -J<flag> : 指定傳遞給運行jmap的JVM的參數.

jmap示例

-heap
[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: 堆內存初始化配置

    • MinHeapFreeRatio: 對應jvm啓動參數-XX:MinHeapFreeRatio設置JVM堆最小空閒比率(default 40)
    • MaxHeapFreeRatio: 對應jvm啓動參數 -XX:MaxHeapFreeRatio設置JVM堆最大空閒比率(default 70)
    • MaxHeapSize: 對應jvm啓動參數-XX:MaxHeapSize=設置JVM堆的最大大小
    • NewSize: 對應jvm啓動參數-XX:NewSize=設置JVM堆的‘新生代’的默認大小
    • MaxNewSize: 對應jvm啓動參數-XX:MaxNewSize=設置JVM堆的‘新生代’的最大大小
    • OldSize: 對應jvm啓動參數-XX:OldSize=<value>:設置JVM堆的‘老生代’的大小
    • NewRatio: 對應jvm啓動參數-XX:NewRatio=:‘新生代’和‘老生代’的大小比率
    • SurvivorRatio: 對應jvm啓動參數-XX:SurvivorRatio=設置年輕代中Eden區與Survivor區的大小比值
    • PermSize: 對應jvm啓動參數-XX:PermSize=<value>:設置JVM堆的‘永生代’的初始大小
    • MaxPermSize: 對應jvm啓動參數-XX:MaxPermSize=<value>:設置JVM堆的‘永生代’的最大大小
  • Heap Usage: 堆內存使用狀況

    • PS Young Generation: 當前的年輕代內存分佈
      • Eden Space: Eden區內存分佈
        • capacity: 區總容量
        • used: 區已使用
        • free: 區剩餘容量
      • From Space: 其中一個Survivor區的內存分佈
      • To Space: 另外一個Survivor區的內存分佈
    • PS Old Generation: 當前的老年代內存分佈
    • PS Perm Generation: 當前的 「永生代」 內存分佈
-histo

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,而後再統計信息.

jmap -dump:format=b,file=heapDump 進程

這個命令執行,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/

jmap使用總結

  • 若是程序內存不足或者頻繁GC,頗有可能存在內存泄露狀況,這時候就要藉助Java堆Dump查看對象的狀況
  • 要製做堆Dump能夠直接使用jvm自帶的jmap命令
  • 使用jmap -histo:[live]查看堆內存中的對象的狀況.若是有大量對象在持續被引用,並無被釋放掉,那就產生了內存泄露,就要結合代碼,把不用的對象釋放掉
  • 用 jmap -dump:format=b,file=<fileName>命令將堆信息保存到一個文件中,再借助jhat命令查看詳細內容
  • 在內存出現泄露、溢出或者其它前提條件下,建議多dump幾回內存,把內存文件進行編號歸檔,便於後續內存整理分析.

命令行工具-jhat

jhat(JVM Heap Analysis Tool) 命令與jmap搭配使用, 用來分析jmap生成的堆轉儲快照, jhat內置了一個微型的HTTP/HTML服務器, 方便在瀏覽器中查看jmap生成的HeadpDump文件.

jhat語法

[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" 

參數說明

  • -stack : 關閉對象分配調用棧跟蹤,若是分配位置信息在堆轉儲中不可用,則必須將此標誌設置爲false. 默認值爲true.
  • -refs : 關閉對象引用跟蹤;默認值爲true;默認狀況下,返回的指針是指向其餘特定對象的對象,如反向連接或輸入引用,會統計/計算堆中的全部對象.
  • -port : 設置jhat HTTP server 的端口號. 默認值7000.
  • -exclude : 指定對象查詢時須要排除的數據成員列表文件;例如:若是文件列列出了 java.lang.String.value,那麼當從某個特定對象Object o計算可達的對象列表時,引用路徑涉及 java.lang.String.value的都會被排除.
  • -baseline : 指定一個基準堆轉儲;在兩個heap dumps中有相同object ID的對象會被標記爲不是新的,其餘對象被標記爲新的(new),在比較兩個不一樣的堆轉儲時頗有用.
  • -debug : 設置debug 級別. 0表示不輸出調試信息.
  • -version :啓動後只顯示版本信息就退出

jhat示例

生成java堆轉儲文件,並用jhat分析
[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便可, 通常查看堆異常狀況主要看這個兩各部分

  • 平臺外的全部對象信息: Show instance counts for all classes (excluding platform)
  • 以樹狀圖形式展現堆狀況: Show heap histogram

具體排查時須要結合代碼,觀察是否大量應該被回收的對象在一直被引用或者是否有佔用內存特別大的對象沒法被回收.

jhat對象查詢

OQL語句的執行頁面: http://ip:端口/oql/
OQL幫助信息頁面爲: http://ip:端口/oqlhelp/

參考文檔


 

著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處

相關文章
相關標籤/搜索