EN
注册
我要评分
文档获取效率
文档正确性
内容完整性
文档易理解
在线提单
论坛求助

调优过程

前提条件

  • 服务器和操作系统正常运行。
  • PC端已经安装SSH远程登录工具。
  • 需要优化的Java程序。

操作步骤

实践使用demo请参考testdemo

  1. 进行在线分析。

    在概览页签下观察每种状态的线程数量。

    图1 概览1

    发现有大量线程处于阻塞状态,有锁竞争的可能。

  2. 查看CPU页签的线程列表,执行多次线程转储操作。
    图2 线程转储
  3. 查看线程转储页签。
    图3 线程转储-线程概览

    通过状态字段,筛选出阻塞状态的线程,点击Monitor详情,查看对应锁信息。

    图4 线程转储
  4. 查看线程转储页签的Monitor详情。
    观察发现锁0x0000000101c98088,已被持有,有50个线程同时在竞争该锁。
    图5 Monitor详情

    结合线程概览页面的栈信息,找到具体代码进行分析 。

    图6 线程概览

    发现使用的不是JUC提供的工具锁,程序中使用的是synchronized;如果锁竞争比较激烈,该类锁将升级成重量级,会导致上下文切换比较频繁,从而影响性能和关键业务的阻塞。

  5. 问题分析。

    根据线程转储中提供的锁的类型和位置,咱们就可以分析代码的业务逻辑,从而找到调优方案。下面介绍两种锁竞争的调优方法,仅供参考。

    • 情况一:使用synchronized,但在业务上竞争比较激烈。

      将synchronized替换成JUC提供的工具锁(ReentrantLock等)。

    • 情况二:使用JUC 提供的工具锁,但在业务上竞争比较激烈。

      这种情况需要加入其他策略去提高性能,如加入线程池,限制竞争锁的线程数;如果是读写分离的场景,可以考虑使用ReadWriteLock,从业务的实际情况去考虑。

总结

Java中的锁竞争问题一旦发生很难定位具体的代码位置,因为程序干扰因素比较多,但是可以根据线程转储去定位,其中的栈信息提供了发生锁竞争的代码位置。

如果发现多个线程都试图锁住相同的锁地址,说明应用正面临锁竞争,在进行其他程序调优时,需要根据鲲鹏DevKit Java性能分析工具采集的实际结果和对应的优化建议进行调优操作,具体的调优思路可以参考本次实践。