tomcat服务无响应堆栈分析

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

[[email protected] ~]# pgrep java
10472
[[email protected] ~]# 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.
[[email protected] ~]# jmap -dump:file=dump_dtb  10472
Dumping heap to /root/dump_dtb ...
Heap dump file created

[[email protected] ~]# 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关键字,如果一定要用,要确保程序逻辑中有明确的超时控制机制,并且超时时间不要太长。

时间: 2024-08-28 19:01:18

tomcat服务无响应堆栈分析的相关文章

cloudstack下libvirtd服务无响应问题

在cloudstack4.5.2版本下,偶尔出现libvirtd服务无响应的情况,导致virsh命令无法使用,同时伴随cloudstack master丢失该slave主机连接的情况.最初怀疑是libvirtd服务或版本的问题,经过分析和排查最终确定是cloudstack-agent的问题.但是在官网上并没有找到类似的bug提交,该问题可能还存在于更高的版本,需要时间进一步从根本上分析.下面是该问题的处理过程,在此记录下,关注和使用cloudstack的朋友可以参考. 众所周知,cloudsta

线程的两种睡眠方法&amp;ANR(进程/服务无响应)

1 method1: try { 2 Thread.sleep(3000); 3 } catch (InterruptedException e) { 4 e.printStackTrace(); 5 } 6 method2: SystemClock.sleep(3000); ANR(Application Not Responding) 在Android上,如果应用程序有一段时间响应不够灵敏,系统会向用户显示一个对话框,这个对话框称作应用程序无响应(ANR:Application Not Re

因redis线程池挂起导致tomcat无响应

上周线上服务器突然出错,tomcat服务莫名其妙的无响应,查看内存和cpu,一切正常,查看nginx日志,发现一直返回499的错误码,看来是程序里面某一处出错,导致tomcat挂起.没啥好办法,线程,堆dump出来之后,重启tomcat服务,应用恢复正常. 分析了dump出来的堆之后,发现有5百多的redis的连接挂起在那里,查看了redis连接池的配置,发现一个pool最多500个,再仔细查看代码,发现代码逻辑有问题,当应用传入一个key,从redis里面获取一个值,如果该key不存在,代码里

Stop a hung service 关闭一个无响应的windows 服务

If you ever have trouble with a service being stuck in a 'starting' or 'stopping' state, you can run a couple of simple commands to kill the service. 1. Query the process To kill the service you have to know its PID or Process ID. To find this just t

Nagios通过check_http监控一台web应用服务器上多个tomcat服务

如何在nagios监控tomcat,是一个比较简单又复杂的事情,简单是因为如果只监控web应用服务器的一个tomcat服务是否正常运行,那么比较简单:如果要监控tomcat的其他比如连接数比如jvm内存使用率等就比较复杂,google没有适合的监控脚本:如果要监控web应用上面的多个tomcat服务器,而且很多tomcat服务都是跳转式的,那就需要多做很多事情. 一般通常都使用tcp tomcat端口的方式,不过这有一个bug就是tomcat假死的情况下,tcp 端口是OK的,但是tomcat里

Tomcat 内存溢出,堆栈配置各种调整

java -Xmx1610M -version java -Xmx1610m -version 网摘的tomcat内存溢出解决方案 Tomcat内存溢出的原因 在生产环境中tomcat内存设置不好很容易出现内存溢出.造成内存溢出是不一样的,当然处理方式也不一样. 这里根据平时遇到的情况和相关资料进行一个总结.常见的一般会有下面三种情况: 1.OutOfMemoryError: Java heap space 2.OutOfMemoryError: PermGen space 3.OutOfMem

JMX堆栈分析

线程堆栈: 线程堆栈也称线程调用堆栈,是虚拟机中线程(包括锁)状态的一个瞬间快照,即系统在某一个时刻所有线程的运行状态,包括每一个线程的调用堆栈,锁的持有情况.虽然不同的虚拟机打印出来的格式有些不同,但是线程堆栈的信息都包含: 线程名字,id,线程的数量等. 线程的运行状态,锁的状态(锁被哪个线程持有,哪个线程在等待锁等) 调用堆栈(即函数的调用层次关系)调用堆栈包含完整的类名,所执行的方法,源代码的行数. 借助堆栈信息可以帮助分析很多问题,如线程死锁,锁争用,死循环,识别耗时操作等等.在多线程

用友T6客户端点击系统管理admin.exe,一直无响应

用友T6客户端 点击系统管理admin.exe,一直无响应 公司财务经理,反应客户端T6 点击 系统管理 模块 ,一直打不开或过很长时间跳出窗口..... 经过分析,发现 T6 Admin.exe 一直无响应,很可能是客户端默认是不会安装SQL 服务管理器这个组件,导致客户端无法远程连接T6服务器的SQL服务 所以,下载MSDE2000组件,安装即可! 安装完成后,进行系统注册,就可以远程管理T6相关模板了............

nginx connect() failed (111: Connection refused) while connecting to upstream,请求无响应错误

2015/01/02 16:01:36 [error] 29002#0: *714153 connect() failed (111: Connection refused) while connecting to upstream, client: 172.16.3.32, server: bizorder.qianbao666.com, request: "POST /api/queryOrder/orderList HTTP/1.1", upstream: "http: