天天看点

java常用工具相关资料jps 简介jinfo 简介jstatd 简介jstat 简介jstack 简介jmap 简介jhat 简介jdb简介jconsole简介jvisualvm 简介常见问题

相关资料

  • jstat java性能统计工具
  • jstack java线程堆栈工具
  • jmap java内存映像工具
  • jps java进程查看
  • jinfo java配置信息工具
  • jhat java堆快照分析工具
  • jconsole 可视化java工具
  • jvisualvm 可视化java工具
  • jstatd java统计监控后台程序
  • jdb java调试工具

jps 简介

列出所有java进程

options

-q 仅输出VM标识符,不包括class name,jar name,arguments in main method 
-m 输出main method的参数 
-l 输出完全的包名,应用主类名,jar的完全路径名 
-v 输出jvm参数 
-V 输出通过flag文件传递到JVM中的参数(.hotspotrc文件或-XX:Flags=所指定的文件 
-Joption 传递参数到vm,例如:-J-Xms48m
           

hostid

[protocol:][[//]hostname][:port][/servername]
           

Examples

jps rmi:.*.*.*:   #  查看远程机器的java进程id(需要远程开启jstatd进程)
jps -lmv                #  本地java进程的详细信息
           

jinfo 简介

jinfo可以输出并修改运行时的java 进程的opts。用处比较简单,用于输出JAVA系统参数及命令行参数。一般不支持修改,jdk8废弃改命令。

jinfo [ option ] pid
jinfo [ option ] executable core
jinfo [ option ] [server[email protected]]remote-hostname-or-IP 
           

Options

no option  打印命令行参数和系统属性
-flags  打印命令行参数
-sysprops  打印系统属性
-h  帮助
           

jstatd 简介

虚拟机的监控的守护进程,主要用于监控JVM的创建与终止,并提供一个接口允许远程监控工具(jps|jstat|jstack…)依附到在本地主机上运行的JVM。

Options

-nr 当一个存在的RMI Registry没有找到时,不尝试创建一个内部的RMI Registry
-p port 端口号,默认为
-n rminame 默认为JStatRemoteHost;如果多个jstatd服务开始在同一台主机上,rminame唯一确定一个jstatd服务
-J jvm选项
           

Usages

  • 通过策略文件(jstatd.all.policy),允许jstatd服务器在没有任何安全例外的情况下运行。该策略没有授权所有权限给所有代码库那么自由,但却比授予最小的权限来运行jstatd服务器更自由.个人建议要及时关闭,有风险。
grant codebase "file:${java.home}/../lib/tools.jar" {  
   permission java.security.AllPermission;  
};
           
  • 基于策略文件,启动jstatd,同时启动RMI日志(一般没必要就不要开启了)
nohup rmiregistry &jstatd -J-Djava.security.policy=jstatd.all.policy -J-Djava.rmi.server.logCalls=true -p   &
           

jstat 简介

jvm监控统计工具,包括gc信息,类编译信息等。

jstat [ generalOption | outputOptions vmid [interval[s|ms] [count]] ]
           

vmid

[protocol:][//]lvmid[@hostname[:port]/servername]
           

options

-class 类加载情况的统计
Loaded 加载了的类的数量
Bytes 加载了的类的大小,单为Kb
Unloaded 卸载了的类的数量
Bytes 卸载了的类的大小,单为Kb
Time 花在类的加载及卸载的时间
-compiler HotSpot中即时编译器编译情况的统计
Compiled 编译任务执行的次数
Failed 编译任务执行失败的次数
Invalid 编译任务非法执行的次数
Time 执行编译花费的时间
FailedType 最后一次编译失败的编译类型
FailedMethod 最后一次编译失败的类名及方法名
-gc JVM中堆的垃圾收集情况的统计
S0C 新生代中Survivor space中S0当前容量的大小(KB)
S1C 新生代中Survivor space中S1当前容量的大小(KB)
S0U 新生代中Survivor space中S0容量使用的大小(KB)
S1U 新生代中Survivor space中S1容量使用的大小(KB)
EC Eden space当前容量的大小(KB)
EU Eden space容量使用的大小(KB)
OC Old space当前容量的大小(KB)
OU Old space使用容量的大小(KB)
PC Permanent space当前容量的大小(KB)
PU Permanent space使用容量的大小(KB)
YGC 从应用程序启动到采样时发生 Young GC 的次数
YGCT 从应用程序启动到采样时 Young GC 所用的时间(秒)
FGC 从应用程序启动到采样时发生 Full GC 的次数
FGCT 从应用程序启动到采样时 Full GC 所用的时间(秒)
GCT T从应用程序启动到采样时用于垃圾回收的总时间(单位秒),它的值等于YGC+FGC
-gccapacity 新生代、老生代及持久代的存储容量情况
NGCMN 新生代的最小容量大小(KB)
NGCMX 新生代的最大容量大小(KB)
NGC 当前新生代的容量大小(KB)
S0C 当前新生代中survivor space 0的容量大小(KB)
S1C 当前新生代中survivor space 1的容量大小(KB)
EC Eden space当前容量的大小(KB)
OGCMN 老生代的最小容量大小(KB)
OGCMX 老生代的最大容量大小(KB)
OGC 当前老生代的容量大小(KB)
OC 当前老生代的空间容量大小(KB)
PGCMN 持久代的最小容量大小(KB)
PGCMX 持久代的最大容量大小(KB)
PGC 当前持久代的容量大小(KB)
PC 当前持久代的空间容量大小(KB)
YGC 从应用程序启动到采样时发生 Young GC 的次数
FGC 从应用程序启动到采样时发生 Full GC 的次数
-gccause 这个选项用于查看垃圾收集的统计情况(这个和-gcutil选项一样),如果有发生垃圾收集,它还会显示最后一次及当前正在发生垃圾收集的原因,它比-gcutil会多出最后一次垃圾收集原因以及当前正在发生的垃圾收集的原因。用于查看垃圾收集的统计情况,包括最近发生垃圾的原因
LGCC 最后一次垃圾收集的原因,可能为“unknown GCCause”、“System.gc()”等
GCC 当前垃圾收集的原因
-gcutil 新生代、老生代及持代垃圾收集的情况
S0 Heap上的 Survivor space 0 区已使用空间的百分比
S1 Heap上的 Survivor space 1 区已使用空间的百分比
E Heap上的 Eden space 区已使用空间的百分比
O Heap上的 Old space 区已使用空间的百分比
P Perm space 区已使用空间的百分比
YGC 从应用程序启动到采样时发生 Young GC 的次数
YGCT 从应用程序启动到采样时 Young GC 所用的时间(单位秒)
FGC 从应用程序启动到采样时发生 Full GC 的次数
FGCT 从应用程序启动到采样时 Full GC 所用的时间(单位秒)
GCT 从应用程序启动到采样时用于垃圾回收的总时间(单位秒),它的值等于YGC+FGC
-printcompilation HotSpot编译方法的统计
Compiled 编译任务执行的次数
Size 方法的字节码所占的字节数
Type 编译类型
Method 指定确定被编译方法的类名及方法名,类名中用“/”而不是“.”做为命名分隔符,方法名是被指定的类中的方法,这两个字段的格式是由HotSpot中的“-XX:+PrintComplation”选项确定的。
-JjavaOption 用于将给定的javaOption传给java应用程序加载器,例如,“-J-Xms48m”将把启动内存设置为48M。如果想查看可以传递哪些选项到应用程序加载器中,可以相看如下的文档
Linux and Solaris: http://docs.oracle.com/javase/1.5.0/docs/tooldocs/solaris/java.html
Windows: http://docs.oracle.com/javase/1.5.0/docs/tooldocs/windows/java.html
-t n 用于在输出内容的第一列显示时间戳,这个时间戳代表的时JVM开始启动到现在的时间
-h n 用于指定每隔几行就输出列头,如果不指定,默认是只在第一行出现列头

Examples

jstat -gc rmi:pid@10.*.*.*:   #  查看远程机器 指定pid的gc 信息
jstat -class  pid         #  本地java进程[pid]的类加载情况的统计
           

Reference

  • jvm内存结构及管理
  • jvm gc 详情

jstack 简介

jstack用于打印出给定的Java进程ID或core file或远程调试服务的Java堆栈信息,如果是在64位机器上,需要指定选项”-J-d64”,Windows的jstack使用方式只支持以下的这种方式:jstack [-l] pid

如果java程序崩溃生成core文件,jstack工具可以用来获得core文件的java stack和native stack的信息,从而可以轻松地知道java程序是如何崩溃和在程序何处发生问题。另外,jstack工具还可以附属到正在运行的java程序中,看到当时运行的java程序的java stack和native stack的信息, 如果现在运行的java程序呈现hung的状态,jstack是非常有用的。

jstack [ option ] pid                    #(Usually)
jstack [ option ] executable core
jstack [ option ] [[email protected]]remote-hostname-or-IP
           

Option

-F          #当’jstack [-l] pid’没有相应的时候强制打印栈信息

-l          #长列表. 打印关于锁的附加信息,例如属于java.util.concurrent的ownable synchronizers列表.

-m          #打印java和native c/c++框架的所有栈信息.

-h|-help    #打印帮助信息
           

jstack内容详解

  • java线程状态
  • java线程状态转移
    java常用工具相关资料jps 简介jinfo 简介jstatd 简介jstat 简介jstack 简介jmap 简介jhat 简介jdb简介jconsole简介jvisualvm 简介常见问题
 线程被阻塞可能是由于下面五方面的原因:

  1.调用sleep(毫秒数),使线程进入睡眠状态。在规定时间内,这个线程是不会运行的。
  2.用suspend()暂停了线程的执行。除非收到resume()消息,否则不会返回“可运行”状态。(已废弃)
  3.用wait()暂停了线程的执行。除非线程收到notify()或notifyAll()消息,否则不会变成“可运行”状态。
  4.线程正在等候一些IO操作完成。
  5.线程试图调用另一个对象的“同步”方法,但那个对象处于锁定状态,暂时无法使用。

  所涉及到的两种池:

  Wait pool 等待池

  Lock pool 锁池
           
  • jstack 几种线程状态介绍
Runnable                #包括runnable和running两种状态
Wait on condition       #线程等待IO,sleep等
Waiting for monitor entry #对象在Lockpool中 
in Object.wait()        #对象在wait pool 中需要notify才能进入锁池,并最终获得锁进入Runnable状态
           
  • jstack分析实例

jstack分析几种常见问题

io异常

  • 当jstack dump 的线程中存在大量的 wait on condition ,观察堆栈是不是网络IO 导致的,结合系统指令 netstat 观察是不是已经超过带宽的上限。
  • lsof -p $pid 观察当前进程的io请况
  • iostat 观察系统总体的io情况

死锁

jstack 会自动识别并表示死锁。

热锁

热锁,也往往是导致系统性能瓶颈的主要因素。其表现特征为,由于多个线程对临界区,或者锁的竞争,可能出现:

  • 频繁的线程的上下文切换:从操作系统对线程的调度来看,当 线程在等待资源而阻塞的时候,操作系统会将之切换出来,放到等待的队列,当线程获得资源之后,调度算法会将这个线程切换进去,放到执行队列中。
  • 大量的系统调用:因为线程的上下文切换,以及热锁的竞争,或 者临界区的频繁的进出,都可能导致大量的系统调用。
  • 大部分 CPU开销用在 “系统态 ”:线程上下文切换,和系统调用,都会导致 CPU在 “系统态 ”运行,换而言之,虽然系统很忙碌,但是 CPU用在 “用户态 ”的比例较小,应用程序得不到充分的 CPU资源。
  • 随着 CPU数目的增多,系统的性能反而下降。因为 CPU数目多,同 时运行的线程就越多,可能就会造成更频繁的线程上下文切换和系统态的 CPU开销,从而导致更糟糕的性能。

结合系统指令top -p $pid; shift +h ;以及具体堆栈分析定位系统态的cpu占用过高的具体原因。

cpu过高

  • 结合系统指令定位具体的进程中某个导致进程cpu过高的线程pid。
  • printf(“%x\n”) $pid 转换十六进制;对应堆栈中的nid(nid 是实际的本地系统的进程id,tid 是虚拟机中的进程id)。
  • 通过堆栈信息,分析该线程pid的具体信息。

程序效率低,执行慢

分析是否存在死锁,热锁。分析WAITING,BLOCK,状态的线程。观察是不是IO导致的,网络IO,带宽问题,还是网络断开导致的空等待,还是线程sleep,waitpool中的对象是不是忘记唤醒,lockpool的对象是不是永远获取不到锁,TIMED_WAIT设置的时间是否合理,或者磁盘IO导致的,具体问题结合堆栈信息和系统状态进行分析。(vmstat,iostat,netstat,uptime,top。lsof等指令根据需要配合使用。)

jmap 简介

打印出某个java进程内存的,所有‘对象’的情况。64位机器上,需要指定选项”-J-d64”。

jmap [ option ] pid                    #(Usually)
jmap [ option ] executable core
jmap [ option ] [[email protected]]remote-hostname-or-IP
           

Options

-dump:[live,]format=b,file=<filename> #使用hprof二进制形式,输出jvm的heap内容到文件。live子选项是可选的,假如指定live选项,那么只输出活的对象到文件. 
-finalizerinfo                        #打印正等候回收的对象的信息.
-heap                                 #打印heap的概要信息,GC使用的算法,heap的配置及wise heap的使用情况.
-histo[:live]                         #打印每个class的实例数目,内存占用,类全名信息. VM的内部类名字开头会加上前缀”*”. 如果live子参数加上后,只统计活的对象数量. 
-permstat                             #打印classload和jvm heap长久层的信息. 包含每个classloader的名字,活泼性,地址,父classloader和加载的class数量. 另外,内部String的数量和占用内存数也会打印出来. 
-F                                    #强迫在pid没有相应的时候使用-dump或者-histo参数. 在这个模式下,live子参数无效. 
-h | -help                            #打印辅助信息 
-J                                    #传递参数给jmap启动的jvm. 
           

Example

jmap  -dump:format=b,file=tomcat.bin 
jmap  -histo:live $cpid
           

jhat 简介

用来分析Java堆的命令,可以将堆中的对象以html的形式显示出来,包括对象的数量,大小等等,并支持对象查询语言.

  • jhat tomcat.bin (jmap dump的文件)
  • dump出来的堆很大,在启动时会报堆空间不足的错。添加 -J-Xmx512m,重定义最大堆内存
  • ip:7000 浏览器查看
  • http://ip:7000/histo/ 类大小,数量统计信息
  • http://ip:7000/showRoots/ gc根集
  • http://ip:7000/oql/ 对象查询
  • http://ip:7000/oqlhelp/ 对象查询语法

jdb简介

java debug 工具,一般使用IDE,debug更快捷,无界面程序可以使用该工具调试。

命令行调试

jdb调试命令

JAVA_OPTS="$JAVA_OPTS -Xdebug -Xrunjdwp:transport=dt_socket,address=8787,server=y,suspend=y"
jdb -attach .:
           

jconsole简介

JConsole 是一个内置 Java 性能分析器,可以从命令行或在 GUI shell 中运行。

Usages jconsole

jvisualvm 简介

jconsole的升级版。

Usages jvisualvm

常见问题

sun.jvm.hotspot.debugger.DebuggerException 异常

出现场景

- jinfo pid

- jstack -F

- jmap -heap

Solve

sudo vim /etc/sysctl.d/-ptrace.conf 
修改 kernel.yama.ptrace_scope =  
sudo /sbin/sysctl -e -p  /etc/sysctl.d/-ptrace.conf 重新加载该调整信息,无需重启,永久有效
echo  | sudo tee /proc/sys/kernel/yama/ptrace_scope 当前有效,重启后无效,建议使用后恢复本来的设置,ubuntu从后修改了该默认设置,应该是出于安全考虑,线上环境,更应该谨慎使用。
           

sun.jvm.hotspot.runtime.VMVersionMismatchException

工具和pid的jvm不一致导致的,使用启动当前pid的java命令所在的文件夹下的工具指令。