本文共 1423 字,大约阅读时间需要 4 分钟。
模拟一段死循环的代码
/** * 死循环Map测试 * 解决死循环问题:因为dataMap为空的时候,iterator.next()一直没有被调用到,就会导致死循环 */ public MapdeadIterator() { Map paramMap = new HashMap<>(); paramMap.put("onekey", new Object()); Map dataMap = new HashMap<>(); Iterator iterator = paramMap.keySet().iterator(); while (iterator.hasNext()) { System.out.println("iterator.hasNext()"); for (String keySet : dataMap.keySet()) { System.out.println("for.dataMap.keySet()()"); if(iterator.next().equals(keySet)){ iterator.remove(); } } } return paramMap; }
在controller中,外部调用死循环的代码
/** * 导致cpu飙高 * @return */ @RequestMapping("/deadIterator") @ResponseBody public String deadIterator() { deadLockService.deadIterator(); return "deadIterator"; }
java -Xmx32M -Xms32M -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./ -jar order-0.0.1-SNAPSHOT.jar &
第一步:top命令,观察到pid 4906占用高
第二步:jps -l,果然是我们java应用对应pid=4906
第三步:导出线程栈信息,生成目录在本地,当然你也可以直接在服务器看
直接jstack 4906 即可。
jstack 4906 >> 4906.txt
线程文件导出
sz 4906.txt
打开分析:找一下没有可疑的信息,果真如图所示,定位到我们代码,导致排查完毕。
补充命令示例
top -Hp pidprintf "%x\n" 线程pid
jstack pid | grep 转换成16进制的数值 -A 30 jstack pid sudo jsatck pid >> 789.txt
转载地址:http://wjuh.baihongyu.com/