目录
2. jps(Java Virtual Machine Process Status Tool)
5.jmap(Memory Map)和 jhat(Java Heap Analysis Tool)
八、进程管理
1. ps (Process Status)
ps命令用来列出系统中当前运行的那些进程。ps命令列出的是当前那些进程的快照,就是执行ps命令的那个时刻的那些进程,经常与grep结合使用。如果想要动态的显示进程信息,就可以使用top命令。
语法格式如下:
- ps [参数]
常用命令如下:
- ps -ef 显示所有进程信息,连同命令行(PID、START TIME、CMD等)。
- ps -au 显示较详细的资讯。
- ps -aux 列出目前所有的正在内存当中的程序,显示所有包含其他使用者的进程(PID、CPU、MEMORY、START TIME、CMD等)。-aux显示信息更加详细,而-ef能够显示父程序ID。
- ps -aux > ps001.txt 把所有进程显示出来,并输出到ps001.txt文件
- ps -aux | grep 61500
- ps -aux | grep pentaho
各相关信息的意义:
- F 代表这个程序的旗标 (flag), 4 代表使用者为 super user
- S 代表这个程序的状态 (STAT),关于各 STAT 的意义将在内文介绍
- UID 程序被该 UID 所拥有
- PID 就是这个程序的 ID !
- PPID 则是其上级父程序的ID
- C CPU 使用的资源百分比
- PRI 这个是 Priority (优先执行序) 的缩写,详细后面介绍
- NI 这个是 Nice 值,在下一小节我们会持续介绍
- ADDR 这个是 kernel function,指出该程序在内存的那个部分。如果是个 running的程序,一般就是 "-"
- SZ 使用掉的内存大小
- WCHAN 目前这个程序是否正在运作当中,若为 - 表示正在运作
- TTY 登入者的终端机位置
- TIME 使用掉的 CPU 时间。
- CMD 所下达的指令为何。
2. jps(Java Virtual Machine Process Status Tool)
jps主要用来输出JVM中运行的进程状态信息。语法格式如下:
- jps [options] [hostid]
如果不指定hostid就默认为当前主机或服务器。
命令行参数选项说明如下:
- -q:不输出类名、Jar名和传入main方法的参数。
- -m:输出传入main方法的参数。
- -l:输出main类或Jar的全限名。
- -v:输出传入JVM的参数。
注:ps命令能够同时将上述参数的效果打印出来。(另外,有些进程ps命令能够打印出来,而jps命令不行,如MySQL服务)
ps -ef | grep <进程ID> / ps -aux | grep <进程ID> 约等于 jps -mv | grep <进程ID>
3.top
top命令用来动态显示进程状态信息,但会消耗很多系统资源。(ps是一个静态的)语法格式如下:
- top [参数]
常用参数:
- -d <num>:指定更新的间隔,以秒计算。
- -q:没有任何延迟的更新。如果使用者有超级用户,则top命令将会以最高的优先序执行。
- -c:显示进程完整的路径与名称。
- -S:累积模式,会将己完成或消失的子行程的CPU时间累积起来。
- -s:安全模式。
- -i:不显示任何闲置(Idle)或无用(Zombie)的行程。
- -n <num>:显示更新的次数,完成后将会退出top。
- -p <PID>:显示指定进程的状态信息。
- top -Hp <PID>:监控进程中各线程的资源使用情况。
top命令使用过程中,还可以使用一些交互的命令来完成其它参数的功能。这些命令是通过快捷键启动的。
- <空格>:立刻刷新。
- P:根据CPU使用大小进行排序。
- M:根据使用内存大小进行排序。
- T:根据时间、累计时间排序。
- q:退出top命令。
- m:切换显示内存信息。
- t:切换显示进程和CPU状态信息。
- c:切换显示命令名称和完整命令行。
- W:将当前设置写入~/.toprc文件中。这是写top配置文件的推荐方法。
- 1:切换显示各核的CPU和内存使用详情。
4.jstack
jstack主要用来查看某个Java进程内的线程堆栈信息。语法格式如下:
- jstack [option] pid
- jstack [option] executable core
- jstack [option] [server-id@]remote-hostname-or-ip
命令行参数选项说明如下:
- -l:long listings,会打印出额外的锁信息,在发生死锁时可以用jstack -l pid来观察锁持有情况
- -m:mixed mode,不仅会输出Java堆栈信息,还会输出C/C++堆栈信息(比如Native方法)
举例,jstack可以定位到线程堆栈,根据堆栈信息我们可以定位到具体代码,所以它在JVM性能调优中使用得非常多。下面我们来一个实例找出某个Java进程中最耗费CPU的Java线程并定位堆栈信息,用到的命令有ps、top、printf、jstack、grep。
(1)找出Java进程ID,部署在服务器上的Java应用名称为pentaho****
- ps -ef | grep pentaho
得到的进程ID为31524。
(2)找出该进程内最耗费CPU的线程,可以使用
- ps -Lfp pid
- ps -mp pid -o THREAD, tid, time
- top -Hp pid
TIME列就是各个Java线程耗费的CPU时间,CPU时间最长的是线程ID为21742的线程。
(3)转换对应的16进制,得到54ee。
- printf "%x\n" 21742
(4)使用jstack命令,输出进程31524的堆栈信息,然后根据线程ID的十六进制值grep.
- jstack 31524 | grep 54ee
可以看到CPU消耗在PollIntervalRetrySchedulerThread这个类的Object.wait(),定位到下面的代码:
它是轮询任务的空闲等待代码,上面的sigLock.wait(timeUntilContinue)就对应了前面的Object.wait()。
5.jmap(Memory Map)和 jhat(Java Heap Analysis Tool)
jmap用来查看堆内存使用状况,一般结合jhat使用。
jmap语法格式如下:
- jmap [option] pid
- jmap [option] executable core
- jmap [option] [server-id@]remote-hostname-or-ip
常用命令:
- -clstats <PID>:打印进程的类加载器和类加载器加载的持久代对象信息,输出:类加载器名称、对象是否存活(不可靠)、对象地址、父类加载器、已加载的类大小等信息。
- -heap <PID>:查看进程堆内存使用情况,包括使用的GC算法、堆配置参数和各代中堆内存使用情况。
- -histo[:live] <PID>:查看堆内存中的对象数目、大小统计直方图,如果带上live则只统计活对象。(哪些实例数量异常)
class name是对象类型,说明如下:
用jmap把进程内存使用情况dump到文件中,再用jhat分析查看。
不太习惯用jhat,直接 jmap -histo:live <PID> | grep xxx 就挺好,xxx替换为项目package路径中的标识性字符串。
jmap进行dump命令格式如下:
- jmap -dump:format=b,file=<dumpFileName> <PID>
如:
dump出来的文件可以用MAT、VisualVM等工具查看,这里用jhat查看:(别忘了放开防火墙端口)
- jhat -port <Port> <dumpFileName>
浏览器中查看,输入: 主机地址:9998。
6.jstat(JVM统计监测工具)
观察classloader,compiler,gc等相关信息,可以实时监控资源和性能。(感觉用处不大)语法格式如下:
- jstat -options pid [options]
命令行参数选项说明如下
- -class:统计class loader行为信息
- -compile:统计编译行为信息
- -gc:统计jdk gc时heap信息
- -gccapacity:统计不同的generations(不知道怎么翻译好,包括新生区,老年区,permanent区)相应的heap容量情况
- -gccause:统计gc的情况,(同-gcutil)和引起gc的事件
- -gcnew:统计gc时,新生代的情况
- -gcnewcapacity:统计gc时,新生代heap容量
- -gcold:统计gc时,老年区的情况
- -gcoldcapacity:统计gc时,老年区heap容量
- -gcpermcapacity:统计gc时,permanent区heap容量
- -gcutil:统计gc时,heap情况
比如下面输出的是GC信息,采样时间间隔为250ms,采样数为4:
各列含义:
7.Arthas
官网资料:简介 | arthas
(0)安装和启用
安装:zip包解压安装。
启用:java -jar arthas-boot.jar
在当前程序列表中选择需要监控的服务序号后,进入操作页面。
(1)接口耗时分析trace
前端接口请求慢时,可以使用 trace命令分析。查看方法内部调用路径,并输出方法路径上的每个节点上耗时。
- 前端F12查看请求慢的接口。
- 使用trace命令分析该方法中每一步的耗时,命令:trace 全路径类名 方法名。如 trace com.xxx.xxx.xxController getXXXFunction 。
- 使用trace命令分析上一步中耗时最长的方法,直至找到问题点。
trace我用的最多,下面的没有深入了解过。
(2)线程查看:thread
查看当前线程信息,查看线程的堆栈。
- thread <PID>:打印指定线程的调用栈。
- thread -b:找出当前阻塞其他线程的线程
- thread -n <num>:指定最忙的前num个线程并打印堆栈。
(3)查看JVM已加载的类信息:sc
- sc com.aaa.bbb.*:模糊搜索。
- sc -d com.aaa.bbb.ccc:准确搜索。
(4)查看已加载类的方法信息:sm
调用栈中获取类和方法名。
- sm com.aaa.bbb.ccc:查看类中的所有方法。
- sm com.aaa.bbb.ccc ddd:查看类中的指定方法。(可以通过*进行模糊搜索)
- sm com.aaa.bbb.ccc | grep ddd:通过grep过滤。(但信息好像很少)
(5)反编译:jad
- jad com.aaa.bbb.ccc:反编译指定已加载类的源码。(仍然混淆)
(6)monitor:方法执行监控
(7)watch:方法执行数据观测
(8)stack:输出当前方法被调用的调用路径(调用栈)
(9)tt:方法执行数据的时空隧道,记录下指定方法每次调用的入参和返回信息,并能对这些不同的时间下调用进行观测