zoukankan      html  css  js  c++  java
  • tomcat服务无响应堆栈分析

    tomcat服务突然无响应了,导出内存堆栈和线程堆栈,分析后发现是同步锁使用不合理导致的。

    [root@prd-dtb-web-01 ~]# pgrep java
    10472
    [root@prd-dtb-web-01 ~]# jmap -heap 10472
    Attaching to process ID 10472, please wait...
    Debugger attached successfully.
    Server compiler detected.
    JVM version is 25.111-b14

    using thread-local object allocation.
    Parallel GC with 2 thread(s)

    Heap Configuration:
       MinHeapFreeRatio         = 0
       MaxHeapFreeRatio         = 100
       MaxHeapSize              = 1983905792 (1892.0MB)
       NewSize                  = 41943040 (40.0MB)
       MaxNewSize               = 661127168 (630.5MB)
       OldSize                  = 83886080 (80.0MB)
       NewRatio                 = 2
       SurvivorRatio            = 8
       MetaspaceSize            = 21807104 (20.796875MB)
       CompressedClassSpaceSize = 1073741824 (1024.0MB)
       MaxMetaspaceSize         = 17592186044415 MB
       G1HeapRegionSize         = 0 (0.0MB)

    Heap Usage:
    PS Young Generation
    Eden Space:
       capacity = 487063552 (464.5MB)
       used     = 26314992 (25.095932006835938MB)
       free     = 460748560 (439.40406799316406MB)
       5.402784070362958% used
    From Space:
       capacity = 72351744 (69.0MB)
       used     = 71945680 (68.61274719238281MB)
       free     = 406064 (0.3872528076171875MB)
       99.43876404693161% used
    To Space:
       capacity = 84934656 (81.0MB)
       used     = 0 (0.0MB)
       free     = 84934656 (81.0MB)
       0.0% used
    PS Old Generation
       capacity = 254279680 (242.5MB)
       used     = 136744120 (130.40935516357422MB)
       free     = 117535560 (112.09064483642578MB)
       53.77705367570071% used

    36326 interned Strings occupying 4333960 bytes.
    [root@prd-dtb-web-01 ~]# jmap -dump:file=dump_dtb  10472
    Dumping heap to /root/dump_dtb ...
    Heap dump file created

    [root@prd-dtb-web-01 ~]# jstack 10472 > thread_dtb

    使用Eclipse MemoryAnalyzer对内存堆栈的分析,发现线程已经占满了。

    通过对线程堆栈文件内容的分析,发现大量线程都处于waiting to lock状态,进一步发现,对应代码使用了synchronized同步锁,一个线程内部访问数据库发生了超时,长时间占用了该锁,导致其它线程都处于等待状态。

    ...

    "http-nio-8002-exec-26" #52 daemon prio=5 os_prio=0 tid=0x00007f951c01b000 nid=0x291e waiting for monitor entry [0x00007f9530dc9000]
       java.lang.Thread.State: BLOCKED (on object monitor)
        at cn.friendsure.tdtb.services.WeixinPayService.payed(WeixinPayService.java:273)
        - waiting to lock <0x000000008a9103b0> (a cn.friendsure.tdtb.services.WeixinPayService)
        at sun.reflect.GeneratedMethodAccessor264.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)
        at org.springframework.web.bind.annotation.support.HandlerMethodInvoker.invokeHandlerMethod(HandlerMethodInvoker.java:175)
        at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.invokeHandlerMethod(AnnotationMethodHandlerAdapter.java:446)
        at org.springframework.web.servlet.mvc.annotation.AnnotationMethodHandlerAdapter.handle(AnnotationMethodHandlerAdapter.java:434)

    ...

    at cn.friendsure.tdtb.logics.OrderLogic.transferOrder(OrderLogic.java:531)
        - locked <0x000000008a9104e0> (a cn.friendsure.tdtb.logics.OrderLogic)
        at cn.friendsure.tdtb.services.WeixinPayService.transferOrder(WeixinPayService.java:478)
        at cn.friendsure.tdtb.services.WeixinPayService.payed(WeixinPayService.java:399)
        - locked <0x000000008a9103b0> (a cn.friendsure.tdtb.services.WeixinPayService)
        at sun.reflect.GeneratedMethodAccessor264.invoke(Unknown Source)
        at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
        at java.lang.reflect.Method.invoke(Method.java:498)

    ...

    【解决方案

    去掉不必要的同步锁。

    【总结

    涉及IO的方法,尽量不要使用synchronized关键字,如果一定要用,要确保程序逻辑中有明确的超时控制机制,并且超时时间不要太长。

  • 相关阅读:
    Tomcat安装和使用
    mysql5.7.18安装配置
    Memcached安装与使用
    Redis
    nginx的安装与使用
    python操作mysql
    Paramiko模块
    协程与异步IO
    Queue与生产者消费者模型
    C# 生成验证码 方法二
  • 原文地址:https://www.cnblogs.com/lavezhang/p/6106356.html
Copyright © 2011-2022 走看看