java 程序 top 100% jstack 问题解决

远程服务器,觉得很卡,输入命令要反应半天,感觉异常,top了下,发现有个java进程cpu占用率100%了,大感不妙,于是乎开启了问题解决之旅

  1. 查看进程中各线程负载 ps -mp [pid] -o THREAD,tid,time | sort -rn | more

    ps查看运行情况.png

  2. 打印tid 16进制线程号 printf "%x\n" tid

jstack查看java线程.png
  1. jstack 查看线程信息 jstack pid | grep tid -A 30

定位到了问题出现的代码上,代码是这样写的

while (totals.size() < CommonConstants.ACTIVE_MASTER) {
            //随机再集合里取出元素,添加到新哈希集合
            totals.add(array[random.nextInt(strings.size())]);
        }

这里的 totle 是个 HashSet,haseset 的值时不能重复的 当add相同的值时,hashset会自动去重,长度不会改变,这里显然是死循环了,于是加了个判断,问题解决!

扩展

ps命令

功能:用来显示当前进程的状态

参数:
a 显示所有进程
-a 显示同一终端下的所有程序
-A 显示所有进程
c 显示进程的真实名称
e 显示环境以及传递给命令的参数,最多不超过 80 个字符。
-f 生成一个完整列表。
-N 反向选择
x 显示没有终端的进程除了有一个控制终端的进程。
u 显示面向用户的输出。这包括 USER、PID、%CPU、%MEM、SZ、RSS、TTY、STAT、STIME、TIME 和 COMMAND 字段
-m 标志将使用额外的行来显示与进程相关联的线程,您必须将 -o 标志与 THREAD 字段说明符配合使用来显示与线程相关的额外列。
-p Plist 仅显示有关 Plist 变量指定的进程号的进程的信息。Plist 变量是一个用逗号分隔的进程标识号列表,或者是一个用双引号(" ")引起来、并且各个进程标识号之间用逗号和/或一个或多个空格分隔的进程标识号列表。

printf %x 打印16进制数

jstack 命令
jstack是java虚拟机自带的一种堆栈跟踪工具
jstack 后跟 pid参数,列出进程内的线程

> RUNNABLE,在虚拟机内执行的。运行中状态,可能里面还能看到locked字样,表明它获得了某把锁。 
> BLOCKED,受阻塞并等待监视器锁。被某个锁(synchronizers)給block住了。 
> WATING,无限期等待另一个线程执行特定操作。等待某个condition或monitor发生,一般停留在park(), wait(), sleep(),join() 等语句里。 
> TIMED_WATING,有时限的等待另一个线程的特定操作。和WAITING的区别是wait() 等语句加上了时间限制 wait(timeout)。 
> TERMINATED,已退出的。 

grep 命令

> -A是显示匹配后和它后面的n行。 
> -B是显示匹配行和它前面的n行。 
> -C是匹配行和它前后各n行。 

你可能感兴趣的:(java 程序 top 100% jstack 问题解决)