java常用工具,
java常用工具,
相关资料
- jstat java性能统计工具
- jstack java线程堆栈工具
- jmap java内存映像工具
- jps java进程查看
- jinfo java配置信息工具
- jhat java堆快照分析工具
- jconsole 可视化java工具
- jvisualvm 可视化java工具
- jstatd java统计监控后台程序
- jdb java调试工具
jps 简介
列出所有java进程
jps [ options ] [ hostid ]
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:10.*.*.*:2020 # 查看远程机器的java进程id(需要远程开启jstatd进程)
jps -lmv # 本地java进程的详细信息
jinfo 简介
jinfo可以输出并修改运行时的java 进程的opts。用处比较简单,用于输出JAVA系统参数及命令行参数。一般不支持修改,jdk8废弃改命令。
jinfo [ option ] pid
jinfo [ option ] executable core
jinfo [ option ] [server-id@]remote-hostname-or-IP
Options
no option 打印命令行参数和系统属性
-flags 打印命令行参数
-sysprops 打印系统属性
-h 帮助
jstatd 简介
虚拟机的监控的守护进程,主要用于监控JVM的创建与终止,并提供一个接口允许远程监控工具(jps|jstat|jstack…)依附到在本地主机上运行的JVM。
Options
-nr 当一个存在的RMI Registry没有找到时,不尝试创建一个内部的RMI Registry
-p port 端口号,默认为1099
-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 2020&jstatd -J-Djava.security.policy=jstatd.all.policy -J-Djava.rmi.server.logCalls=true -p 2020 &
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.*.*.*:2020 # 查看远程机器 指定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 ] [server-id@]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线程状态转移
线程被阻塞可能是由于下面五方面的原因:
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 ] [server-id@]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 9142
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 127.0.0.1:8787
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/10-ptrace.conf
修改 kernel.yama.ptrace_scope = 0
sudo /sbin/sysctl -e -p /etc/sysctl.d/10-ptrace.conf 重新加载该调整信息,无需重启,永久有效
echo 0 | sudo tee /proc/sys/kernel/yama/ptrace_scope 当前有效,重启后无效,建议使用后恢复本来的设置,ubuntu从11.04后修改了该默认设置,应该是出于安全考虑,线上环境,更应该谨慎使用。
sun.jvm.hotspot.runtime.VMVersionMismatchException
工具和pid的jvm不一致导致的,使用启动当前pid的java命令所在的文件夹下的工具指令。
相关文章
- 暂无相关文章
用户点评