博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
聊聊elasticsearch的DeadlockAnalyzer
阅读量:7099 次
发布时间:2019-06-28

本文共 5713 字,大约阅读时间需要 19 分钟。

  hot3.png

本文主要研究一下elasticsearch的DeadlockAnalyzer

DeadlockAnalyzer

elasticsearch-7.0.1/server/src/main/java/org/elasticsearch/monitor/jvm/DeadlockAnalyzer.java

public class DeadlockAnalyzer {    private static final Deadlock NULL_RESULT[] = new Deadlock[0];    private final ThreadMXBean threadBean = ManagementFactory.getThreadMXBean();    private static DeadlockAnalyzer INSTANCE = new DeadlockAnalyzer();    public static DeadlockAnalyzer deadlockAnalyzer() {        return INSTANCE;    }    private DeadlockAnalyzer() {    }    public Deadlock[] findDeadlocks() {        long deadlockedThreads[] = threadBean.findMonitorDeadlockedThreads();        if (deadlockedThreads == null || deadlockedThreads.length == 0) {            return NULL_RESULT;        }        Map
threadInfoMap = createThreadInfoMap(deadlockedThreads); Set
> cycles = calculateCycles(threadInfoMap); Set
> chains = calculateCycleDeadlockChains(threadInfoMap, cycles); cycles.addAll(chains); return createDeadlockDescriptions(cycles); } private Deadlock[] createDeadlockDescriptions(Set
> cycles) { Deadlock result[] = new Deadlock[cycles.size()]; int count = 0; for (LinkedHashSet
cycle : cycles) { ThreadInfo asArray[] = cycle.toArray(new ThreadInfo[cycle.size()]); Deadlock d = new Deadlock(asArray); result[count++] = d; } return result; } private Set
> calculateCycles(Map
threadInfoMap) { Set
> cycles = new HashSet<>(); for (Map.Entry
entry : threadInfoMap.entrySet()) { LinkedHashSet
cycle = new LinkedHashSet<>(); for (ThreadInfo t = entry.getValue(); !cycle.contains(t); t = threadInfoMap.get(Long.valueOf(t.getLockOwnerId()))) { cycle.add(t); } if (!cycles.contains(cycle)) { cycles.add(cycle); } } return cycles; } private Set
> calculateCycleDeadlockChains(Map
threadInfoMap, Set
> cycles) { ThreadInfo allThreads[] = threadBean.getThreadInfo(threadBean.getAllThreadIds()); Set
> deadlockChain = new HashSet<>(); Set
knownDeadlockedThreads = threadInfoMap.keySet(); for (ThreadInfo threadInfo : allThreads) { Thread.State state = threadInfo.getThreadState(); if (state == Thread.State.BLOCKED && !knownDeadlockedThreads.contains(threadInfo.getThreadId())) { for (LinkedHashSet
cycle : cycles) { if (cycle.contains(threadInfoMap.get(Long.valueOf(threadInfo.getLockOwnerId())))) { LinkedHashSet
chain = new LinkedHashSet<>(); ThreadInfo node = threadInfo; while (!chain.contains(node)) { chain.add(node); node = threadInfoMap.get(Long.valueOf(node.getLockOwnerId())); } deadlockChain.add(chain); } } } } return deadlockChain; } private Map
createThreadInfoMap(long threadIds[]) { ThreadInfo threadInfos[] = threadBean.getThreadInfo(threadIds); Map
threadInfoMap = new HashMap<>(); for (ThreadInfo threadInfo : threadInfos) { threadInfoMap.put(threadInfo.getThreadId(), threadInfo); } return unmodifiableMap(threadInfoMap); } //......}
  • DeadlockAnalyzer提供了findDeadlocks方法用于返回死锁线程的信息,该方法通过ThreadMXBean的findMonitorDeadlockedThreads方法获取deadlockedThreads数组,如果该数组为null或空,则返回NULL_RESULT,否则往下计算
  • createThreadInfoMap方法根据threadIds从ThreadMXBean获取对应的threadInfo信息,然后组装成threadId与threadInfo的map;calculateCycles方法则是遍历该map,然后根据threadInfo的getLockOwnerId()构建cycles
  • calculateCycleDeadlockChains方法则根据threadInfoMap及cycles构建cycleDeadlockChains,添加到cycles中,最后通过createDeadlockDescriptions方法构建Deadlock数组

Deadlock

elasticsearch-7.0.1/server/src/main/java/org/elasticsearch/monitor/jvm/DeadlockAnalyzer.java

public static class Deadlock {        private final ThreadInfo members[];        private final String description;        private final Set
memberIds; public Deadlock(ThreadInfo[] members) { this.members = members; Set
builder = new HashSet<>(); StringBuilder sb = new StringBuilder(); for (int x = 0; x < members.length; x++) { ThreadInfo ti = members[x]; sb.append(ti.getThreadName()); sb.append(" > "); if (x == members.length - 1) { sb.append(ti.getLockOwnerName()); } builder.add(ti.getThreadId()); } this.description = sb.toString(); this.memberIds = unmodifiableSet(builder); } public ThreadInfo[] members() { return members; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; Deadlock deadlock = (Deadlock) o; if (memberIds != null ? !memberIds.equals(deadlock.memberIds) : deadlock.memberIds != null) return false; return true; } @Override public int hashCode() { int result = members != null ? Arrays.hashCode(members) : 0; result = 31 * result + (description != null ? description.hashCode() : 0); result = 31 * result + (memberIds != null ? memberIds.hashCode() : 0); return result; } @Override public String toString() { return description; } }
  • Deadlock包含了members、description、memberIds三个属性,其构造器会根据members来构建description

小结

  • DeadlockAnalyzer提供了findDeadlocks方法用于返回死锁线程的信息,该方法通过ThreadMXBean的findMonitorDeadlockedThreads方法获取deadlockedThreads数组,如果该数组为null或空,则返回NULL_RESULT,否则往下计算
  • createThreadInfoMap方法根据threadIds从ThreadMXBean获取对应的threadInfo信息,然后组装成threadId与threadInfo的map;calculateCycles方法则是遍历该map,然后根据threadInfo的getLockOwnerId()构建cycles
  • calculateCycleDeadlockChains方法则根据threadInfoMap及cycles构建cycleDeadlockChains,添加到cycles中,最后通过createDeadlockDescriptions方法构建Deadlock数组

doc

转载于:https://my.oschina.net/go4it/blog/3053414

你可能感兴趣的文章
按照Right-BICEP要求设计四则运算2程序的单元测试用例
查看>>
SpringMVC-Handler-Return Values返回值
查看>>
KVM网络桥接模式解说
查看>>
WebApp开发之--"rem"单位(转)
查看>>
TOPCODER->Practice Room->SRAM 144 DIV 1 (550)
查看>>
mysql 远程连接速度慢的解决方案
查看>>
一刷leetcode——dp
查看>>
android软键盘挡住输入框问题解决方法
查看>>
Angular企业级开发(10)-Smart Table插件开发
查看>>
POJ-3295 Tautology 构造法
查看>>
HDU-3573 Buy Sticks
查看>>
验证码的封装
查看>>
javascript与服务器1
查看>>
自制面试宝典
查看>>
PHP对象的复制
查看>>
使用代码模拟请求和提交网页数据
查看>>
C语言内存分配
查看>>
2、Flutter 填坑记录篇
查看>>
android学习笔记(四)
查看>>
Ubuntu下快速搭建ACdream Online Judge v1.5.3
查看>>