jdk下载慢怎么办 jdk下载快速方法( 二 )


  • UnixFileSystem中需要对一个新文件的路径按照操作系统标准进行标准化 。
  • 标准化的结果存放在ExpiringCache对象中 。
多个线程都在争相调用ExpiringCache#put操作,这侧面反映了文件列表的高频变化,这说明系统中存在高频的Flush和Merge操作 。
这加剧了我关于使用姿势的怀疑:”细雨绵绵”式的写入,被动触发Flush,如果周期相同,意味着同时Flush,多个Shard同时Merge的概率变大 。
于是,我开始在测试环境中模拟这种使用方式,创建类似的分片数量,控制写入频率 。计划让测试程序至少运行一天的时间,观察是否可以复现此问题 。在程序运行的同时,我继续调查Thread Dump日志 。
第3点现象中,仅仅是做一次hash计算,却表现出特别慢的样子 。如果将这三点现象综合起来,可以发现所有的调用点都在做CPU计算 。按理说,CPU应该特别的忙碌 。
等问题在现场复现的时候,客户协助获取了CPU使用率与负载信息,结果显示CPU资源非常闲 。在这之前,同事也调研过IO资源,也是非常闲的 。这排除了系统资源方面的影响 。此时也发现,每一次复现的节点是随机的,与机器无关 。
一天过去后,在本地测试环境中,问题没能复现出来 。尽管使用姿势不优雅,但却不像是问题的症结所在 。
03 诡异的STW中断
通过jstack命令获取Thread Dump日志时,需要让JVM进程进入Safepoint,相当于整个进程先被挂起 。获取到的Thread Dump日志,也恰恰是进程挂起时每个线程的瞬间状态 。
所有忙碌的线程都刚好在做CPU计算,但CPU并不忙碌 。这提示需要进一步调查GC日志 。
现场应用并未开启GC日志 。考虑到问题当前尚未复现,通过jstat工具来查看GC次数与GC统计时间的意义不太大 。让现场人员在jvm.options中手动添加了如下参数来开启GC日志:
8:-XX:+PrintGCDetails
8:-XX:+PrintGCDateStamps
8:-XX:+PrintTenuringDistribution
8:-XX:+PrintGCApplicationStoppedTime
8:-Xloggc:logs/gc.log
8:-XX:+UseGCLogFileRotation
8:-XX:NumberOfGCLogFiles=32
8:-XX:GCLogFileSize=32m
添加
PrintGCApplicationStoppedTime是为了将每一次JVM进程发生的STW(Stop-The-World)中断记录在GC日志中 。通常,此类STW中断都是因GC引起,也可能与偏向锁有关 。
刚刚重启,现场人员把GC日志tail的结果发了过来,这是为了确认配置已生效 。诡异的是,刚刚重启的进程居然在不停的打印STW日志:

jdk下载慢怎么办 jdk下载快速方法


关于STW日志(”…Total time for which application threads were stopped…”),这里有必要简单解释一下:
JVM有时需要执行一些全局操作,典型如GC、偏向锁回收,此时需要暂停所有正在运行的Thread,这需要依赖于JVM的Safepoint机制,Safepoint就好比一条大马路上设置的红灯 。JVM每一次进入STW(Stop-The-World)阶段,都会打印这样的一行日志:
2020-09-10T13:59:43.210+0800: 73032.559: Total time for which application threads were stopped: 0.0002853 seconds, Stopping threads took: 0.0000217 seconds在这行日志中,提示了STW阶段持续的时间为0.0002853秒,而叫停所有的线程(Stopping threads)花费了0.0000217秒,前者包含了后者 。通常,Stopping threads的时间占比极小,如果过长的话可能与代码实现细节有关,这里不过多展开 。
回到问题,一开始就打印大量的STW日志,容易想到与偏向锁回收有关 。直到问题再次复现时,拿到了3个节点的完整的GC日志,发现无论是YGC还是FGC,触发的频次都很低,这排除了GC方面的影响 。
出现的大量STW日志,使我意识到该现象极不合理 。有同学提出怀疑,每一次中断时间很短啊?写了一个简单的工具,对每一分钟的STW中断频次、中断总时间做了统计:

推荐阅读