jstack 排查死循环

调用触发死循环的请求
  • 请求无响应,程序陷入死循环;
[root@jvm001 ~]# curl http://localhost:8088/loop
使用top检查进程状态
  • 发现PID=265的进程的CPU占用率为99%,从而确定出问题的进程为265;
[root@jvm001 ~]# top
top - 01:09:43 up  1:22,  3 users,  load average: 0.36, 0.15, 0.06
Tasks:  10 total,   1 running,   9 sleeping,   0 stopped,   0 zombie
Cpu(s):100.0%us,  0.0%sy,  0.0%ni,  0.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:    997088k total,   933772k used,    63316k free,     8524k buffers
Swap:   524284k total,     4688k used,   519596k free,   449012k cached

   PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                                                                           
   265 root      20   0 2180m 128m  16m S 99.9 13.2   0:30.60 java                                                                                                                                               
     1 root      20   0 66296 5312 4828 S  0.0  0.5   0:00.03 sshd                                                                                                                                               
     5 root      20   0 98.2m 6968 5952 S  0.0  0.7   0:00.52 sshd                                                                                                                                               
     7 root      20   0 13028 3184 2796 S  0.0  0.3   0:00.03 bash                                                                                                                                               
   212 root      20   0 98.3m 6920 5916 S  0.0  0.7   0:00.58 sshd                                                                                                                                               
   214 root      20   0 13028 3040 2676 S  0.0  0.3   0:00.01 bash                                                                                                                                               
   294 root      20   0 14948 1992 1764 R  0.0  0.2   0:00.04 top                                                                                                                                                
   295 root      20   0 98.2m 6904 5896 S  0.0  0.7   0:00.03 sshd                                                                                                                                               
   297 root      20   0 13028 2992 2708 S  0.0  0.3   0:00.00 bash                                                                                                                                               
   312 root      20   0 75164 5940 5176 S  0.0  0.6   0:00.00 curl
使用jstack输出265号进程的信息
  • 用jstack将265号进程的信息重定向到文件265.txt;
  • 用sz将265.txt下载到本机;
[root@jvm001 ~]# jstack 265 > 265.txt
[root@jvm001 ~]# sz 265.txt 
rz
使用top检查265号进程中的线程信息
  • 发现PID为282的线程CPU占用率异常;
  • 注意这个282是十进制的,而jstack输出的线程号是十六进制的,需做转换;
[root@jvm001 ~]# top -p 265 -H
top - 01:11:42 up  1:24,  3 users,  load average: 0.99, 0.45, 0.18
Tasks:  27 total,   1 running,  26 sleeping,   0 stopped,   0 zombie
Cpu(s):100.0%us,  0.0%sy,  0.0%ni,  0.0%id,  0.0%wa,  0.0%hi,  0.0%si,  0.0%st
Mem:    997088k total,   914796k used,    82292k free,     8572k buffers
Swap:   524284k total,     5540k used,   518744k free,   431036k cached

   PID USER      PR  NI  VIRT  RES  SHR S %CPU %MEM    TIME+  COMMAND                                                                                                                                           
   282 root      20   0 2181m 128m  16m R 99.7 13.2   2:21.75 java                                                                                                                                               
   265 root      20   0 2181m 128m  16m S  0.0 13.2   0:00.00 java                                                                                                                                               
   266 root      20   0 2181m 128m  16m S  0.0 13.2   0:02.24 java                                                                                                                                               
   267 root      20   0 2181m 128m  16m S  0.0 13.2   0:00.35 java                                                                                                                                               
   268 root      20   0 2181m 128m  16m S  0.0 13.2   0:00.00 java                                                                                                                                               
   269 root      20   0 2181m 128m  16m S  0.0 13.2   0:00.00 java                                                                                                                                               
   270 root      20   0 2181m 128m  16m S  0.0 13.2   0:00.00 java                                                                                                                                               
   271 root      20   0 2181m 128m  16m S  0.0 13.2   0:02.40 java                                                                                                                                               
   272 root      20   0 2181m 128m  16m S  0.0 13.2   0:01.05 java                                                                                                                                               
   273 root      20   0 2181m 128m  16m S  0.0 13.2   0:00.00 java                                                                                                                                               
   274 root      20   0 2181m 128m  16m S  0.0 13.2   0:00.23 java                                                                                                                                               
   277 root      20   0 2181m 128m  16m S  0.0 13.2   0:00.03 java                                                                                                                                               
   278 root      20   0 2181m 128m  16m S  0.0 13.2   0:00.01 java                                                                                                                                               
   279 root      20   0 2181m 128m  16m S  0.0 13.2   0:00.00 java                                                                                                                                               
   280 root      20   0 2181m 128m  16m S  0.0 13.2   0:00.01 java                                                                                                                                               
   281 root      20   0 2181m 128m  16m S  0.0 13.2   0:00.09 java                                                                                                                                               
   283 root      20   0 2181m 128m  16m S  0.0 13.2   0:00.00 java                                                                                                                                               
   284 root      20   0 2181m 128m  16m S  0.0 13.2   0:00.00 java                                                                                                                                               
   285 root      20   0 2181m 128m  16m S  0.0 13.2   0:00.00 java                                                                                                                                               
   286 root      20   0 2181m 128m  16m S  0.0 13.2   0:00.00 java                                                                                                                                               
   287 root      20   0 2181m 128m  16m S  0.0 13.2   0:00.00 java                                                                                                                                               
   288 root      20   0 2181m 128m  16m S  0.0 13.2   0:00.00 java                                                                                                                                               
   289 root      20   0 2181m 128m  16m S  0.0 13.2   0:00.00 java                                                                                                                                               
   290 root      20   0 2181m 128m  16m S  0.0 13.2   0:00.00 java                                                                                                                                               
   291 root      20   0 2181m 128m  16m S  0.0 13.2   0:00.02 java                                                                                                                                               
   292 root      20   0 2181m 128m  16m S  0.0 13.2   0:00.00 java                                                                                                                                               
   323 root      20   0 2181m 128m  16m S  0.0 13.2   0:00.00 java
将十进制的282转换成十六进制
[root@jvm001 ~]# printf "%x" 282
11a
拿着十六进制的11a在265.txt中排查
  • 定位到了这个方法:com.example.demo.CpuController.loop(CpuController.java:19),从而找到了导致CPU占用过高的代码;
"http-nio-8088-exec-2" #16 daemon prio=5 os_prio=0 tid=0x00007f8828822000 nid=0x11a runnable [0x00007f87f8ffa000]
   java.lang.Thread.State: RUNNABLE
    at java.lang.String.indexOf(String.java:1769)
    at java.lang.String.indexOf(String.java:1718)
    at com.example.demo.CpuController.getPartneridsFromJson(CpuController.java:74)
    at com.example.demo.CpuController.loop(CpuController.java:19)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:189)
    at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:138)
    at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:895)
    at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:800)
    at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
    at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:1038)
    at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:942)
    at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:1005)
    at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:897)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
    at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:882)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.FormContentFilter.doFilterInternal(FormContentFilter.java:92)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:93)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:200)
    at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:200)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:490)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:139)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:74)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
    at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:408)
    at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
    at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:834)
    at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1415)
    at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49)
    - locked <0x00000000f0d74c98> (a org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
    at java.lang.Thread.run(Thread.java:745)

查看造成问题的代码
  • 由于非法的json字符串导致的死循环;
@RestController
public class CpuController {
    
    /**
     * 死循环
     * 由不合法的json串导致
     * */
    @RequestMapping("/loop")
    public List<Long> loop(){
        String data = "{\"data\":[{\"partnerid\":]";
        return getPartneridsFromJson(data);
    }
        
    public static List<Long> getPartneridsFromJson(String data){  
        //{\"data\":[{\"partnerid\":982,\"count\":\"10000\",\"cityid\":\"11\"},{\"partnerid\":983,\"count\":\"10000\",\"cityid\":\"11\"},{\"partnerid\":984,\"count\":\"10000\",\"cityid\":\"11\"}]}  
        //上面是正常的数据  
        List<Long> list = new ArrayList<Long>(2);  
        if(data == null || data.length() <= 0){  
            return list;  
        }      
        int datapos = data.indexOf("data");  
        if(datapos < 0){  
            return list;  
        }  
        int leftBracket = data.indexOf("[",datapos);  
        int rightBracket= data.indexOf("]",datapos);  
        if(leftBracket < 0 || rightBracket < 0){  
            return list;  
        }  
        String partners = data.substring(leftBracket+1,rightBracket);  
        if(partners == null || partners.length() <= 0){  
            return list;  
        }  
        while(partners!=null && partners.length() > 0){  
            int idpos = partners.indexOf("partnerid");  
            if(idpos < 0){  
                break;  
            }  
            int colonpos = partners.indexOf(":",idpos);  
            int commapos = partners.indexOf(",",idpos);  
            if(colonpos < 0 || commapos < 0){  
                //partners = partners.substring(idpos+"partnerid".length());//1  
                continue;
            }  
            String pid = partners.substring(colonpos+1,commapos);  
            if(pid == null || pid.length() <= 0){  
                //partners = partners.substring(idpos+"partnerid".length());//2  
                continue;
            }  
            try{  
                list.add(Long.parseLong(pid));  
            }catch(Exception e){  
                //do nothing  
            }  
            partners = partners.substring(commapos);  
        }  
        return list;  
    }  
    
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值