Skip to content

Commit

Permalink
vjtop的active threads 相关 信息调整 vipshop#139
Browse files Browse the repository at this point in the history
  • Loading branch information
calvin1978 committed Nov 6, 2018
1 parent 4c4a251 commit 9c75f6b
Show file tree
Hide file tree
Showing 5 changed files with 184 additions and 162 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ private void printStacktrace(String command) throws IOException {

try {
long pid = Long.parseLong(pidStr);
app.view.printStack(pid);
app.view.threadPrinter.printStack(pid);
waitForEnter();
} catch (NumberFormatException e) {
tty.println(" Wrong number format for pid");
Expand All @@ -109,7 +109,7 @@ private void printStacktrace(String command) throws IOException {
private void printTopThreadsStack() throws IOException {
try {
app.preventFlush();
app.view.printTopStack();
app.view.threadPrinter.printTopStack();
waitForEnter();
} finally {
app.continueFlush();
Expand All @@ -119,7 +119,7 @@ private void printTopThreadsStack() throws IOException {
private void printAllThreadsName() throws IOException {
try {
app.preventFlush();
app.view.printAllThreads();
app.view.threadPrinter.printAllThreads();
waitForEnter();
} finally {
app.continueFlush();
Expand All @@ -129,7 +129,7 @@ private void printAllThreadsName() throws IOException {
private void printBlockedThreadsStack() throws IOException {
try {
app.preventFlush();
app.view.printBlockedThreads();
app.view.threadPrinter.printBlockedThreads();
waitForEnter();
} finally {
app.continueFlush();
Expand Down
142 changes: 142 additions & 0 deletions vjtop/src/main/java/com/vip/vjtools/vjtop/ThreadPrinter.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
package com.vip.vjtools.vjtop;

import java.io.IOException;
import java.lang.management.LockInfo;
import java.lang.management.ThreadInfo;

/**
* 打印线程名,线程栈信息
*/
public class ThreadPrinter {

private VMDetailView view;

public ThreadPrinter(VMDetailView view) {
this.view = view;
}

/**
* 打印单条线程的stack strace,会造成停顿,但比获取全部线程的stack trace停顿少
*/
public void printStack(long tid) throws IOException {
System.out.printf("%n Stack trace of thread %d:%n", tid);

ThreadInfo info = view.vmInfo.getThreadInfo(tid, 20);
if (info == null) {
System.err.println(" TID not exist:" + tid);
return;
}
printSingleThread(info);
System.out.flush();
}

/**
* 打印所有活跃线程的stack strace,会造成停顿,但比获取全部线程的stack trace停顿少
*/
public void printTopStack() throws IOException {
System.out.printf("%n Stack trace of top %d threads:%n", view.threadLimit);

ThreadInfo[] infos = view.topThreadInfo.getTopThreadInfo();
for (ThreadInfo info : infos) {
if (info == null) {
continue;
}
printSingleThread(info);
}
System.out.flush();
}

public StackTraceElement[] printSingleThread(ThreadInfo info) {
StackTraceElement[] trace = info.getStackTrace();
StringBuilder sb = new StringBuilder(512);

sb.append(" ").append(info.getThreadId()).append(": \"").append(info.getThreadName()).append("\"");

if (view.vmInfo.threadContentionMonitoringSupported) {
sb.append(" (blocked:").append(info.getBlockedCount()).append("/").append(info.getBlockedTime())
.append("ms, wait:").append(info.getWaitedCount()).append("/").append(info.getWaitedTime())
.append("ms");
} else {
sb.append(" (blocked:").append(info.getBlockedCount()).append(" times, wait:").append(info.getWaitedCount())
.append(" times");
}

if (info.isSuspended()) {
sb.append(" ,suspended");
}
if (info.isInNative()) {
sb.append(" ,in native");
}
sb.append(")\n");

sb.append(" java.lang.Thread.State: " + info.getThreadState().toString());
LockInfo lockInfo = info.getLockInfo();
if (lockInfo != null) {
sb.append("(on " + lockInfo + ")");
}
if (info.getLockOwnerName() != null) {
sb.append(" owned by " + info.getLockOwnerId() + ":\"" + info.getLockOwnerName() + "\"");
}
sb.append("\n");
for (StackTraceElement traceElement : trace) {
sb.append("\tat ").append(traceElement).append("\n");
}

System.out.print(sb.toString());

return trace;
}

/**
* 打印所有线程,只获取名称不获取stack,不造成停顿
*/
public void printAllThreads() throws IOException {
System.out.println("\n Thread Id and name of all live threads:");

long tids[] = view.vmInfo.getAllThreadIds();
ThreadInfo[] threadInfos = view.vmInfo.getThreadInfo(tids);
for (ThreadInfo info : threadInfos) {
if (info == null) {
continue;
}

String threadName = info.getThreadName();
if (view.threadNameFilter != null && !threadName.toLowerCase().contains(view.threadNameFilter)) {
continue;
}
System.out.println(
" " + info.getThreadId() + "\t: \"" + threadName + "\" (" + info.getThreadState().toString() + ")");
}

if (view.threadNameFilter != null) {
System.out.println(" Thread name filter is:" + view.threadNameFilter);
}
System.out.flush();
}

public void printBlockedThreads() throws IOException {
System.out.println("\n Stack trace of blocked threads:");
int counter = 0;
ThreadInfo[] threadInfos = view.vmInfo.getAllThreadInfo();
for (ThreadInfo info : threadInfos) {
if (info == null) {
continue;
}

String threadName = info.getThreadName();

if (Thread.State.BLOCKED.equals(info.getThreadState())
&& (view.threadNameFilter == null || threadName.toLowerCase().contains(view.threadNameFilter))) {
printSingleThread(info);
counter++;
}
}

System.out.println(" Total " + counter + " blocked threads");

if (view.threadNameFilter != null) {
System.out.println(" Thread name filter is:" + view.threadNameFilter);
}
System.out.flush();
}
}
34 changes: 16 additions & 18 deletions vjtop/src/main/java/com/vip/vjtools/vjtop/TopThreadInfo.java
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ public TopCpuResult topCpuThreads(ThreadInfoMode mode, int threadLimit) throws I
long[] threadCpuTotalTimeArray = vmInfo.getThreadCpuTime(tids);
long[] threadUserCpuTotalTimeArray = vmInfo.getThreadUserTime(tids);

// 过滤CPU占用太少的线程,每秒0.05%CPU (0.5ms cpu time)
long minDeltaCpuTime = (vmInfo.upTimeMills.delta * Utils.NANOS_TO_MILLS / 2000);
// 过滤CPU占用太少的线程,每秒0.01%CPU (0.1ms cpu time)
long minDeltaCpuTime = (vmInfo.upTimeMills.delta * Utils.NANOS_TO_MILLS / 10000);

// 计算本次CPU Time
// 此算法第一次不会显示任何数据,保证每次显示都只显示区间内数据
Expand All @@ -53,7 +53,9 @@ public TopCpuResult topCpuThreads(ThreadInfoMode mode, int threadLimit) throws I
Long deltaThreadCpuTime = threadCpuTotalTime - lastTime;
if (deltaThreadCpuTime >= minDeltaCpuTime) {
result.threadCpuDeltaTimes.put(tid, deltaThreadCpuTime);
result.deltaAllThreadCpu += deltaThreadCpuTime;
result.deltaAllActiveThreadCpu += deltaThreadCpuTime;
} else {
result.deltaAllFreeThreadCpu += deltaThreadCpuTime;
}
}
}
Expand All @@ -70,7 +72,7 @@ public TopCpuResult topCpuThreads(ThreadInfoMode mode, int threadLimit) throws I
Long deltaThreadSysCpuTime = Math.max(0, threadSysCpuTotalTime - lastTime);
if (deltaThreadSysCpuTime >= minDeltaCpuTime) {
result.threadSysCpuDeltaTimes.put(tid, deltaThreadSysCpuTime);
result.deltaAllThreadSysCpu += deltaThreadSysCpuTime;
result.deltaAllActiveThreadSysCpu += deltaThreadSysCpuTime;
}
}
}
Expand All @@ -85,21 +87,19 @@ public TopCpuResult topCpuThreads(ThreadInfoMode mode, int threadLimit) throws I
// 按不同类型排序,过滤
if (mode == ThreadInfoMode.cpu) {
topTidArray = Utils.sortAndFilterThreadIdsByValue(result.threadCpuDeltaTimes, threadLimit);
result.activeThreads = result.threadCpuDeltaTimes.size();
} else if (mode == ThreadInfoMode.syscpu) {
topTidArray = Utils.sortAndFilterThreadIdsByValue(result.threadSysCpuDeltaTimes, threadLimit);
result.activeThreads = result.threadSysCpuDeltaTimes.size();
} else if (mode == ThreadInfoMode.totalcpu) {
topTidArray = Utils.sortAndFilterThreadIdsByValue(result.threadCpuTotalTimes, threadLimit);
result.activeThreads = result.threadCpuTotalTimes.size();
} else if (mode == ThreadInfoMode.totalsyscpu) {
topTidArray = Utils.sortAndFilterThreadIdsByValue(result.threadSysCpuTotalTimes, threadLimit);
result.activeThreads = result.threadSysCpuTotalTimes.size();
} else {
throw new RuntimeException("unkown mode:" + mode);
}

// 获得threadInfo
result.activeThreads = result.threadCpuDeltaTimes.size();

// 获得线程名等信息threadInfo
result.threadInfos = vmInfo.getThreadInfo(topTidArray);

lastThreadCpuTotalTimes = result.threadCpuTotalTimes;
Expand All @@ -111,7 +111,6 @@ public TopCpuResult topCpuThreads(ThreadInfoMode mode, int threadLimit) throws I
return result;
}


public TopMemoryResult topMemoryThreads(ThreadInfoMode mode, int threadLimit) throws IOException {
TopMemoryResult result = new TopMemoryResult();
try {
Expand All @@ -124,9 +123,6 @@ public TopMemoryResult topMemoryThreads(ThreadInfoMode mode, int threadLimit) th
// 批量获取内存分配
long[] threadMemoryTotalBytesArray = vmInfo.getThreadAllocatedBytes(tids);

// 过滤太少的线程,每秒小于1k
long minDeltaMemory = vmInfo.upTimeMills.delta * 1024 / 1000;

// 此算法第一次不会显示任何数据,保证每次显示都只显示区间内数据
for (int i = 0; i < tids.length; i++) {
long tid = tids[i];
Expand All @@ -139,7 +135,7 @@ public TopMemoryResult topMemoryThreads(ThreadInfoMode mode, int threadLimit) th

if (lastBytes != null) {
threadMemoryDeltaBytes = threadMemoryTotalBytes - lastBytes;
if (threadMemoryDeltaBytes >= minDeltaMemory) {
if (threadMemoryDeltaBytes > 0) {
result.threadMemoryDeltaBytesMap.put(tid, threadMemoryDeltaBytes);
result.deltaAllThreadBytes += threadMemoryDeltaBytes;
}
Expand All @@ -156,12 +152,12 @@ public TopMemoryResult topMemoryThreads(ThreadInfoMode mode, int threadLimit) th
long[] topTidArray;
if (mode == ThreadInfoMode.memory) {
topTidArray = Utils.sortAndFilterThreadIdsByValue(result.threadMemoryDeltaBytesMap, threadLimit);
result.activeThreads = result.threadMemoryDeltaBytesMap.size();
} else {
topTidArray = Utils.sortAndFilterThreadIdsByValue(result.threadMemoryTotalBytesMap, threadLimit);
result.activeThreads = result.threadMemoryTotalBytesMap.size();
}

result.activeThreads = result.threadMemoryDeltaBytesMap.size();

result.threadInfos = vmInfo.getThreadInfo(topTidArray);

lastThreadMemoryTotalBytes = result.threadMemoryTotalBytesMap;
Expand All @@ -185,8 +181,10 @@ public static class TopCpuResult {
public ThreadInfo[] threadInfos;
public long activeThreads = 0;

public long deltaAllThreadCpu = 0;
public long deltaAllThreadSysCpu = 0;
public long deltaAllActiveThreadCpu = 0;
public long deltaAllActiveThreadSysCpu = 0;

public long deltaAllFreeThreadCpu = 0;

public LongObjectMap<Long> threadCpuTotalTimes;
public LongObjectMap<Long> threadCpuDeltaTimes;
Expand Down
Loading

0 comments on commit 9c75f6b

Please sign in to comment.