怎样使用jstack诊断Java应用程序故障(转)

本文介绍如何使用jstack命令诊断Java程序中的死锁问题,并通过一个示例展示了如何定位并解决由线程相互等待导致的死锁。

最近一段时间,我们的生产系统升级频繁出现故障,具体故障现象是启动后10来分钟就出现交易缓慢,处理线程耗尽等现象,并且故障发生的频率蛮高的。经过详细的诊断和排查,终于发现了问题,是groovy在osgi中运行会出现classloader死锁,最后我们也解决了这个问题。
??????? 如果单靠通过查看代码是很难去发现这个问题,在这一次故障排查中,我也学到了怎样更好的使用jvm监控工具来进行诊断,主要用到了jstack和jmap命令,jmap上次已经讲过就不再讲了,下面就一个例子来讲怎么使用jstack来对的Java程序进行诊断。
??????? 首先让我们来了解一下jstack这个命令的作用,jstack 是一个可以返回在应用程序上运行的各种各样线程的一个完整转储的实用程序,您可以使用它查明问题。jstack [-l] <pid>,jpid可以通过使用jps命令来查看当前Java程序的jpid值,-l是可选参数,它可以显示线程阻塞/死锁情况。

Java代码 收藏代码

  1. /**
  2. * 死锁例子
  3. * @author crane.ding
  4. * @since 2011-3-20
  5. */
  6. public class DeadLock {?
  7. public static void main(String[] args) {?
  8. final Object obj_1 = new Object(), obj_2 = new Object();?
  9. ??????? Thread t1 = new Thread("t1"){?
  10. @Override
  11. public void run() {?
  12. synchronized (obj_1) {?
  13. try {?
  14. ??????????????????????? Thread.sleep(3000);?
  15. ??????????????????? } catch (InterruptedException e) {}?
  16. synchronized (obj_2) {?
  17. ??????????????????????? System.out.println("thread t1 done.");?
  18. ??????????????????? }?
  19. ??????????????? }?
  20. ??????????? }?
  21. ??????? };?
  22. ??????? Thread t2 = new Thread("t2"){?
  23. @Override
  24. public void run() {?
  25. synchronized (obj_2) {?
  26. try {?
  27. ??????????????????????? Thread.sleep(3000);?
  28. ??????????????????? } catch (InterruptedException e) {}?
  29. synchronized (obj_1) {?
  30. ??????????????????????? System.out.println("thread t2 done.");?
  31. ??????????????????? }?
  32. ??????????????? }?
  33. ??????????? }?
  34. ??????? };?
  35. ??????? t1.start();?
  36. ??????? t2.start();?
  37. ??? }?
  38. }?

??????? 以上DeadLock类是一个死锁的例子,假使在我们不知情的情况下,运行DeadLock后,发现等了N久都没有在屏幕打印线程完成信息。这个时候我们就可以使用jps查看该程序的jpid值和使用jstack来生产堆栈结果问题。

Linux代码 收藏代码

  1. $ java -cp deadlock.jar DeadLock &?
  2. $??

Linux代码 收藏代码

  1. $ jps?
  2. 3076 Jps?
  3. 448 DeadLock?
  4. $ jstack -l 448 > deadlock.jstack?

结果文件deadlock.jstack内容如下:

Xml代码 收藏代码

  1. 2011-03-20 23:05:20?
  2. Full thread dump Java HotSpot(TM) Client VM (19.1-b02 mixed mode, sharing):?
  3. "DestroyJavaVM" prio=6 tid=0x00316800 nid=0x9fc waiting on condition [0x00000000]?
  4. ?? java.lang.Thread.State: RUNNABLE?
  5. ?? Locked ownable synchronizers:?
  6. ??? - None?
  7. "t2" prio=6 tid=0x02bcf000 nid=0xc70 waiting for monitor entry [0x02f6f000]?
  8. ?? java.lang.Thread.State: BLOCKED (on object monitor)?
  9. ??? at com.demo.DeadLock$2.run(DeadLock.java:40)?
  10. ??? - waiting to lock <0x22a297a8> (a java.lang.Object)?
  11. ??? - locked <0x22a297b0> (a java.lang.Object)?
  12. ?? Locked ownable synchronizers:?
  13. ??? - None?
  14. "t1" prio=6 tid=0x02bce400 nid=0xba0 waiting for monitor entry [0x02f1f000]?
  15. ?? java.lang.Thread.State: BLOCKED (on object monitor)?
  16. ??? at com.demo.DeadLock$1.run(DeadLock.java:25)?
  17. ??? - waiting to lock <0x22a297b0> (a java.lang.Object)?
  18. ??? - locked <0x22a297a8> (a java.lang.Object)?
  19. ?? Locked ownable synchronizers:?
  20. ??? - None?
  21. "Low Memory Detector" daemon prio=6 tid=0x02bb9400 nid=0xa6c runnable [0x00000000]?
  22. ?? java.lang.Thread.State: RUNNABLE?
  23. ?? Locked ownable synchronizers:?
  24. ??? - None?
  25. "CompilerThread0" daemon prio=10 tid=0x02bb2800 nid=0xcb8 waiting on condition [0x00000000]?
  26. ?? java.lang.Thread.State: RUNNABLE?
  27. ?? Locked ownable synchronizers:?
  28. ??? - None?
  29. "Attach Listener" daemon prio=10 tid=0x02bb1000 nid=0x7f4 waiting on condition [0x00000000]?
  30. ?? java.lang.Thread.State: RUNNABLE?
  31. ?? Locked ownable synchronizers:?
  32. ??? - None?
  33. "Signal Dispatcher" daemon prio=10 tid=0x02bd2800 nid=0xd80 runnable [0x00000000]?
  34. ?? java.lang.Thread.State: RUNNABLE?
  35. ?? Locked ownable synchronizers:?
  36. ??? - None?
  37. "Finalizer" daemon prio=8 tid=0x02bab000 nid=0xe1c in Object.wait() [0x02d3f000]?
  38. ?? java.lang.Thread.State: WAITING (on object monitor)?
  39. ??? at java.lang.Object.wait(Native Method)?
  40. ??? - waiting on <0x229e1148> (a java.lang.ref.ReferenceQueue$Lock)?
  41. ??? at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:118)?
  42. ??? - locked <0x229e1148> (a java.lang.ref.ReferenceQueue$Lock)?
  43. ??? at java.lang.ref.ReferenceQueue.remove(ReferenceQueue.java:134)?
  44. ??? at java.lang.ref.Finalizer$FinalizerThread.run(Finalizer.java:159)?
  45. ?? Locked ownable synchronizers:?
  46. ??? - None?
  47. "Reference Handler" daemon prio=10 tid=0x02ba6800 nid=0xbe0 in Object.wait() [0x02cef000]?
  48. ?? java.lang.Thread.State: WAITING (on object monitor)?
  49. ??? at java.lang.Object.wait(Native Method)?
  50. ??? - waiting on <0x229e1048> (a java.lang.ref.Reference$Lock)?
  51. ??? at java.lang.Object.wait(Object.java:485)?
  52. ??? at java.lang.ref.Reference$ReferenceHandler.run(Reference.java:116)?
  53. ??? - locked <0x229e1048> (a java.lang.ref.Reference$Lock)?
  54. ?? Locked ownable synchronizers:?
  55. ??? - None?
  56. "VM Thread" prio=10 tid=0x02b6a400 nid=0x568 runnable??
  57. "VM Periodic Task Thread" prio=10 tid=0x02bc8400 nid=0x75c waiting on condition??
  58. JNI global references: 878?
  59. Found one Java-level deadlock:
  60. =============================?
  61. "t2":?
  62. ? waiting to lock monitor 0x02baaeec (object 0x22a297a8, a java.lang.Object),?
  63. ? which is held by "t1"?
  64. "t1":?
  65. ? waiting to lock monitor 0x02baa2bc (object 0x22a297b0, a java.lang.Object),?
  66. ? which is held by "t2"?
  67. Java stack information for the threads listed above:
  68. ===================================================?
  69. "t2":?
  70. ??? at com.demo.DeadLock$2.run(DeadLock.java:40)?
  71. ??? - waiting to lock <0x22a297a8> (a java.lang.Object)?
  72. ??? - locked <0x22a297b0> (a java.lang.Object)?
  73. "t1":?
  74. ??? at com.demo.DeadLock$1.run(DeadLock.java:25)?
  75. ??? - waiting to lock <0x22a297b0> (a java.lang.Object)?
  76. ??? - locked <0x22a297a8> (a java.lang.Object)?
  77. Found 1 deadlock.?

??????? 从这个结果文件我们一看到发现了一个死锁,具体是线程t2在等待线程t1,而线程t1在等待线程t2造成的,同时也记录了线程的堆栈和代码行数,通过这个堆栈和行数我们就可以去检查对应的代码块,从而发现问题和解决问题。

内容概要:本文详细介绍了“秒杀商城”微服务架构的设计与实战全过程,涵盖系统从需求分析、服务拆分、技术选型到核心功能开发、分布式事务处理、容器化部署及监控链路追踪的完整流程。重点解决了高并发场景下的超卖问题,采用Redis预减库存、消息队列削峰、数据库乐观锁等手段保障数据一致性,并通过Nacos实现服务注册发现与配置管理,利用Seata处理跨服务分布式事务,结合RabbitMQ实现异步下单,提升系统吞吐能力。同时,项目支持Docker Compose快速部署和Kubernetes生产级编排,集成Sleuth+Zipkin链路追踪与Prometheus+Grafana监控体系,构建可观测性强的微服务系统。; 适合人群:具备Java基础和Spring Boot开发经验,熟悉微服务基本概念的中高级研发人员,尤其是希望深入理解高并发系统设计、分布式事务、服务治理等核心技术的开发者;适合工作2-5年、有志于型微服务或提升架构能力的工程师; 使用场景及目标:①学习如何基于Spring Cloud Alibaba构建完整的微服务项目;②掌握秒杀场景下高并发、超卖控制、异步化、削峰填谷等关键技术方案;③实践分布式事务(Seata)、服务熔断降级、链路追踪、统一配置中心等企业级中间件的应用;④完成从本地开发到容器化部署的全流程落地; 阅读建议:建议按照文档提供的七个阶段循序渐进地动手实践,重点关注秒杀流程设计、服务间通信机制、分布式事务实现和系统性能优化部分,结合代码调试与监控工具深入理解各组件协作原理,真正掌握高并发微服务系统的构建能力。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符  | 博主筛选后可见
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值