CPU Usage Times Profiling(cpu=times)的例子
现实企业级Java应用开发、维护中,有时候我们会碰到下面这些问题:
OutOfMemoryError,内存不敷
内存泄露
线程死锁
锁争用(Lock Contention)
Java进程消耗CPU过高
......
这些问题在日常开发、维护中可能被很多人忽视(好比有的人遇到上面的问题只是重启处事器或者调大内存,而不会深究问题泉源),但能够理解并解决这些问题是Java措施员进阶的必备要求。本文将对一些常用的JVM性能调优监控工具进行介绍,但愿能起抛砖引玉之用。
一、 jps(Java Virtual Machine Process Status Tool) : 根本工具
jps主要用来输出JVM中运行的进程状态信息。语法格局如下:
jps [options] [hostid]如果不指定hostid就默认为当前主机或处事器。
命令行参数选项说明如下:
-q 不输出类名、Jar名和传入main要领的参数-m 输出传入main要领的参数
-l 输出main类或Jar的全限名
-v 输出传入JVM的参数
好比下面:
[email protected]:/# jps -m -l2458 org.artifactory.standalone.main.Main /usr/local/artifactory-2.2.5/etc/jetty.xml
29920 com.sun.tools.hat.Main -port 9998 /tmp/dump.dat
3149 org.apache.catalina.startup.Bootstrap start
30972 sun.tools.jps.Jps -m -l
8247 org.apache.catalina.startup.Bootstrap start
25687 com.sun.tools.hat.Main -port 9999 dump.dat
21711 mrf-center.jar
二、 jstack
jstack主要用来检察某个Java进程内的线程仓库信息。语法格局如下:
jstack [option] pidjstack [option] executable core
jstack [option] [[email protected]]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。
第一步先找出Java进程ID,我部署在处事器上的Java应用名称为mrf-center:
[email protected]:/# ps -ef | grep mrf-center | grep -v greproot 21711 1 1 14:47 pts/3 00:02:10 java -jar mrf-center.jar
得到进程ID为21711,第二步找出该进程内最耗费CPU的线程,可以使用ps -Lfp pid或者ps -mp pid -o THREAD, tid, time或者top -Hp pid,我这里用第三个,输出如下:
TIME列就是各个Java线程耗费的CPU时间,CPU时间最长的是线程ID为21742的线程,用
printf "%x" 21742
得到21742的十六进制值为54ee,下面会用到。
OK,下一步终于轮到jstack上场了,它用来输出进程21711的仓库信息,然后按照线程ID的十六进制值grep,如下:
[email protected]:/# jstack 21711 | grep 54ee"PollIntervalRetrySchedulerThread" prio=10 tid=0x00007f950043e000 nid=0x54ee in Object.wait() [0x00007f94c6eda000]
可以看到CPU消耗在PollIntervalRetrySchedulerThread这个类的Object.wait(),我找了下我的代码,定位到下面的代码:
// Idle waitgetLog().info("Thread [" + getName() + "] is idle waiting...");
schedulerThreadState = PollTaskSchedulerThreadState.IdleWaiting;
long now = System.currentTimeMillis();
long waitTime = now + getIdleWaitTime();
long timeUntilContinue = waitTime - now;
synchronized(sigLock) {try {
if(!halted.get()) {
sigLock.wait(timeUntilContinue);
}
} catch (InterruptedException ignore) {
}
}
它是轮询任务的空闲期待代码,上面的sigLock.wait(timeUntilContinue)就对应了前面的Object.wait()。
三、 jmap(Memory Map)和 jhat(Java Heap Analysis Tool):
jmap导出堆内存,然后使用jhat来进行分析
jmap语法格局如下:
jmap [option] pidjmap [option] executable core
jmap [option] [[email protected]]remote-hostname-or-ip
如果运行在64位JVM上,可能需要指定-J-d64命令选项参数。
jmap -permstat pid温馨提示: 本文由Jm博客推荐,转载请保留链接: https://www.jmwww.net/file/web/32186.html