

记一次类加载失败导致线程阻塞问题排查
source link: https://www.heapdump.cn/article/2697019
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

作为PerfMa解决方案管理部门的技术专家,我在工作遇见过很多各种问题导致的性能问题,并参与了为客户的系统进行性能诊断调优的全过程。这一次碰到了一个类加载失败导致的性能问题。用文字记录下了问题的整个发现-排查-分析-优化的过程,排查过程中使用了我司商业化产品——XLand性能分析平台,通过文章主要希望跟大家分享下分析和优化思路以及注意点,有兴趣深入了解的同学可以评论交流。
问题现象:
生产上发现有几个接口响应时间很长,并监控到了线程阻塞的情况
分析过程:
先在测试环境上通过对这几个接口进行压测,尝试复现性能问题,并通过XLand监控。
CPU热点分析:
从CPU热点可以看到业务层的clearLocalSessionWithTradeLogin方法,调用了owner组件中的方法(经了解这是一个实现了配置热修改的组件),最终走到findEditor方法时(需确认是否用到了反射)触发了一个类加载的操作,但没找到该类,加载失败。
线程分析:
通过Thread dump的线程视图可以看到有很多Block状态的线程,都是卡在类加载这一步
再来看看是持锁线程在做什么?
发现持锁线程的堆栈是和cpu热点中的线程栈一样的,也是在试图加载类,但是没找到类文件,抛出了ClassNotFoundException
内存分析:
从内存dump的对象视图搜索ClassNotFoundException对象,发现试图加载的类是java.lang.stringEditor对象
分析小结:
综合以上信息看出,业务方法调用了owner组件中的方法,owner组件试图加载StringEditor类,但没找到类文件,抛出了ClassNotFoundException。同时由于多线程情况下,只有一个线程会去加载StringEditor类,其他线程会被阻塞(Block)直至StringEditor加载成功(或者加载失败抛出异常)。但由于缺少StringEditor类文件,因此加载StringEditor类的线程注定会失败,然后又会有其他线程去加载类,然后又失败,周而复始,永远在抛ClassNotFoundException,永远有线程被阻塞(Block)。。。
性能风险点:
1.如果一个类还未被加载到内存中,在多线程调用该类中方法的时候,只有一个线程会去加载该类,其他线程会被阻塞。正常情况下,类加载成功,那么其他线程就不用再阻塞,可以直接该类或对象中的方法。但一旦类加载失败,其他线程还回去视图加载该类,导致永远在抛ClassNotFoundException,永远有线程被阻塞(Block),恶性循环。
2.频繁抛ClassNotFoundException也会产生很多临时对象,导致YGC更频繁,造成更多STW并浪费CPU资源
优化建议:
由于owner组件并非业务强相关,事实上虽然不停在抛ClassNotFoundException,并未导致业务的报错。与开发协商后决定去掉owner组件的调用。
经性能比对测试,不去调用owner组件后,不再抛出ClassNotFoundException,也没有线程阻塞(Block)现象,响应时间大幅下降,TPS成倍增长。相同并发数下,提升最明显的接口TPS增长了10倍左右。
Recommend
-
34
之前面试今日头条的时候,今日头条面试官问我,js执行会阻塞DOM树的解析和渲染,那么css加载会阻塞DOM树的解析和渲染吗?所以,接下来我就来对css加载对DOM树的解析和渲染做一个测试。 为了完成本次测试,先来科普一下,如何利用chrome来设置下载速度
-
30
最近在公司对redis做一些二次开发时,发现一个 randomkey 命令可能导致整个redis实例长时间阻塞的问题,redis版本为3.2.9,以此记录。 问题 由于我们公司使用的是redis集群版Codis,Codis内置的redis版...
-
11
一次 ES-APM 导致的大量线程阻塞问题排查文章>一次 ES-APM 导致的大量线程阻塞问题排查一次 ES-APM 导致的大量线程阻塞问题排查
-
4
关注了就能看到更多这么棒的文章哦~ Avoiding blocking file-name lookups By Jonathan Corbet January 21, 2021 DeepL assisted translation https://lwn.net/Articles/843163/ 一般来说,当人们用 openat2(...
-
9
张哈希apache1天前 线上某个应用的某个实例突然出现某些次请求服务响应极慢的情况,有几次请求超过 60s 才返...
-
4
记一次Synchronized关键字使用不合理,导致的多线程下线程阻塞问题排查 | HeapDump性能社区记一次Synchronized关键字使用不合理,导致的多线程下线程阻塞问题排查杭盖S...
-
15
ants:在Submit中再调用当前Pool的Submit可能导致阻塞 十一月 27, 2021 0 条评论
-
6
Erlang的非阻塞代码加载 由 David Gao 发布于: 2021-12-01 翻译,
-
8
前不久从项目一线同学得到某集群的告警信息,某个时间段 TiDB duration 突然异常升高,持续时间6小时左右,需要定位到具体原因。 第一招,初步判断 由于项目条件苛刻,历经苦难才拿到监控,在此之前只能靠现场同...
-
4
在实际的NW.js程序开发中,我们可能在程序启动时做一些加载前逻辑,比如更新等等,那如何实现等待这些逻辑完成后才开始加载index.html呢?
About Joyk
Aggregate valuable and interesting links.
Joyk means Joy of geeK