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


关于第2点现象,我认真阅读了java.io.UnixFileSystem的源码:
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日志:
关于STW日志(”…Total time for which application threads were stopped…”),这里有必要简单解释一下:
JVM有时需要执行一些全局操作,典型如GC、偏向锁回收,此时需要暂停所有正在运行的Thread,这需要依赖于JVM的Safepoint机制,Safepoint就好比一条大马路上设置的红灯 。JVM每一次进入STW(Stop-The-World)阶段,都会打印这样的一行日志:

猜你喜欢