Java如何定位占用CPU比较高的问题
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java如何定位占用CPU比较高的问题相关的知识,希望对你有一定的参考价值。
参考技术A一、确定消耗CPU的Java进程
从上图可以看到Java进程 27459 消耗的CPU比较高。
二、查找 27459 Java进程消耗CPU线程ID
方式一: top -p [pid] 或 top -H -p [pid]
执行命令后按shift + h (显示进程各线程运行情况)
1)、top -p 27459
2)、shift + h
如下图:
方式二: ps -mp [pid] -o THREAD,tid,time
ps -mp 27459 -o THREAD,tid,time
方式三: pidstat -p [pid] -t 1
pidstat -p 27459 -t 1
备注:pidstat命令需要安装sysstat软件包。
从上面三种方式都可以看出PID是 27460的线程占用CPU比较高。
三、根据Java进程堆栈信息找到对应线程ID
3.1、对应线程ID转换成16进程 printf '%x\\n' [tid]
27460 = 0x6b44
3.2、jstack [pid] 或 jstack [pid] |grep [tid] -A 30
jstack 27460 >> 27460.log
在27460.log文件中查找0x6b44对应的线程,如下图:
备注:
1、jstack 输出的堆栈信息,线程id对应的16进制为小写,查找时要统一按照小写方式查找
2、jstack输出为当前瞬间的堆栈信息,如果遇到间断性出现CPU高的问题时,需要多输出几次
从上面方式定位到代码Test.main(Test.java:4)处导致了CPU偏高的问题,那我们查看下代码具体如何实现的?
代码实现:
public class Test
public static void main(String[] args)
while(true)
从代码层面看该处实现了一个死循环,所以导致了线程占用CPU偏高的问题。
[转]定位占用oracle数据库cpu过高的sql
今天在吃饭的时候我的朋友的数据库出现了问题,cpu占用率为97%,当我看到这个问题的时候我就想到了或许是sql导致的此问题,由于忍不住吃饭,暂时没有帮他看这个问题,这是我饭后自己模拟的故障,进行的分析:
1)查看一下cpu进程占用情况:
看到oracle进程为6331,6517等这几个进程占用cpu过高。
2)查看相关进程信息:
[oracle@oracle-one ~]$ ps -ef | grep 6331 oracle 6331 1 23 20:24 ? 00:02:05 ora_vktm_RHYS oracle 6555 6385 0 20:32 pts/2 00:00:00 grep 6331 [oracle@oracle-one ~]$ ps -ef | grep 6517 <span style="color:#ff0000">oracle 6517 6513 9 20:28 ? 00:00:24 oracleRHYS (DESCRIPTION=(LOCAL=YES)(ADDRESS=(PROTOCOL=beq))) </span>oracle 6557 6385 0 20:33 pts/2 00:00:00 grep 6517 [oracle@oracle-one ~]$
3)查看该会话信息:
SQL> select sid,serial#,username,machine,osuser,process from v$session s 2 where s.paddr=(select addr from v$process p where p.spid=\'&pid\'); Enter value for pid: 6517 old 2: where s.paddr=(select addr from v$process p where p.spid=\'&pid\') new 2: where s.paddr=(select addr from v$process p where p.spid=\'6517\') SID SERIAL# USERNAME MACHINE OSUSER PROCESS ---------- ---------- ----------- ---------------- ------------------------------ ------------------------ 1 21 RHYS oracle-one oracle 6513
可知:session 的信息为sid:1 serial#:21 数据库用户为:RHYS,客户端机器为:oracle-one,操作系统用户为:oracle 进程号:6513
4)查看该会话正在运行的sql:
SQL> select sql_text from v$sqltext 2 where (address,hash_value) in ( select sql_address,sql_hash_value from v$session s 3 4 where s.paddr= 5 (select addr from v$process p where p.spid=\'&pid\')); Enter value for pid: 6517 old 5: (select addr from v$process p where p.spid=\'&pid\')) new 5: (select addr from v$process p where p.spid=\'6517\')) <span style="color:#ff0000">SQL_TEXT ---------------------------------------------------------------- delete from amy_emp</span>
可知,当前用户正在进行删除表的操作,本次就是通过v$process 的spid找到进程号,然后找到v$session 的addr地址,然后找到v$sqltext的sql_address以及sql_hash_value,
通过这两个字段就可以定位出唯一的sql_text,本次通过v$process,v$session,v$sql_text三个视图结合找到相应的sql;
5)后续处理
如果该session为非法的,可以使用如下命令杀掉该会话: alter sytem kill session \'1,21\';
既然找到sql了,那么 我们就可以通知应用相关人员,确认是否在进行相关数据操作。
另外我们也可以使用dbms_system包对该session进行更加详细的跟踪。
比价老的一篇文章,转自:http://www.bitscn.com/pdb/oracle/201309/241814.html
以上是关于Java如何定位占用CPU比较高的问题的主要内容,如果未能解决你的问题,请参考以下文章