当前位置:首页 > Web开发 > 正文

CPU Usage Times Profiling(cpu=times)的例子

2024-03-31 Web开发

现实企业级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 -l
2458 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] pid
jstack [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 grep
root 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 wait
getLog().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] pid
jmap [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