%@ page import="java.lang.management.*,java.lang.Thread.State,java.util.Map,java.util.HashMap,java.util.HashSet"%>
<%@page import="java.text.DecimalFormat,java.util.Date,java.util.List"%>
<%!
/************** page variable and method define start ************************/
final static String versionAndTitle="Thread Checker include GC information v.2010.03.09.";
final static int[] optionSeconds={1,3,5,10,20,30,60,600};
final static String numberPattern="###,###,###,###.###";
final static DecimalFormat format=new DecimalFormat(numberPattern);
final static String TIME_MS="ms";
final static String TIME_SEC=" sec";
final static String TIME_MIN=" min";
public String getTimeString(long nanoSecond) {
long tempMilli=nanoSecond/1000000;
if(tempMilli<1000) {
return format.format(tempMilli/1000.0)+TIME_MS;
} else if(tempMilli<60000) {
return format.format(tempMilli/1000.0) +TIME_SEC;
} else {
return format.format(tempMilli/60000.0) +TIME_MIN;
}
}
final static String SIZE_BYTES=" bytes";
final static String SIZE_KB=" kb";
final static String SIZE_MB=" mb";
final static String memoryPattern="###,###,###,###";
final static DecimalFormat memoryFormat=new DecimalFormat(memoryPattern);
public String getMemoryString(long bytes) {
if(bytes<1024) {
return memoryFormat.format(bytes)+SIZE_BYTES;
} else if(bytes<1024*1024) {
return memoryFormat.format(bytes/1024) +SIZE_KB;
} else {
return memoryFormat.format(bytes/(1024*1024)) +SIZE_MB;
}
}
final static String pageWidth="1024";//"100%";
final static String pageWidth2="1000";//"95%";
/************** page variable and method define end ************************/
final static String STRING_STACK_TRACE_INFO_EXTENDED="
Ordinal | "
+"Thread Name | "
+"Thread State | "
+"Thread Time | "
+"Lock Owner | "
+"Stack Trace information |
";
final static String STRING_STACK_TRACE_INFO_STANDARD="Ordinal | "
+"Thread Name | "
+"Thread State | "
+"Thread Time | ";
%>
<%=versionAndTitle %> by Sangmin, Lee
<%
/************** request value check start ************************/
String STRING_AUTO_REFRESH="autoRefresh";
String STRING_REFRESH_SECOND="refreshSecond";
String STRING_VIEW_ALL_THREAD_INFO="viewAllThreadInfo";
String STRING_VIEW_LOCK_INFO="viewLockInfo";
String STRING_STACK_TRACE_NUMBER="stackTraceNumber";
boolean autoRefresh=false;
String autoRefreshString="";
String autoRefreshReceive=request.getParameter(STRING_AUTO_REFRESH);
if(autoRefreshReceive!=null ) {
autoRefresh=true;
autoRefreshString=" checked ";
//out.println("auto receive="+autoRefreshReceive);
}
int refreshSecond=3;
String refreshSecondReceive=request.getParameter(STRING_REFRESH_SECOND);
if(refreshSecondReceive!=null) {
refreshSecond=Integer.parseInt(refreshSecondReceive);
}
boolean viewAllThreadInfo=false;
String viewAllThreadInfoString="";
String viewAllThreadInfoReceive=request.getParameter(STRING_VIEW_ALL_THREAD_INFO);
if(viewAllThreadInfoReceive!=null) {
viewAllThreadInfo=true;
viewAllThreadInfoString=" checked ";
}
boolean viewLockInfo=false;
String viewLockInfoString="";
String viewLockInfoReceive=request.getParameter(STRING_VIEW_LOCK_INFO);
if(viewLockInfoReceive!=null) {
viewLockInfo=true;
viewLockInfoString=" checked ";
}
int stackTraceNumber=100;
String stackTraceNumberReceive=request.getParameter(STRING_STACK_TRACE_NUMBER);
if(stackTraceNumberReceive!=null) {
stackTraceNumber=Integer.parseInt(stackTraceNumberReceive);
}
/************** request value check end ************************/
%>
<%=versionAndTitle%> by Sangmin, Lee |
|
|
|
|
*Server name : <%=application.getServerInfo() %>.
*Last data received time : <%=new Date() %>
<%
/*************************** Data Collect start *******************/
//long periodMillis=1000;
StringBuffer printDataString=new StringBuffer();
int blocked=0;
int newthread=0;
int runnable=0;
int terminated=0;
int timed_waiting=0;
int waiting=0;
//this attribute is used to change Lock Owner's color
HashSet lockOwnerSet=new HashSet();
printDataString.append("");
/********************* check if I can see the lock info ********************************/
if(viewLockInfo) {
printDataString.append(STRING_STACK_TRACE_INFO_EXTENDED);
} else {
printDataString.append(STRING_STACK_TRACE_INFO_STANDARD);
}
/********************* get ThreadMXBean info ********************************/
ThreadMXBean tmxBean=ManagementFactory.getThreadMXBean();
long threadList[]=tmxBean.getAllThreadIds();
HashMap stackTraceMap=new HashMap();
/********************* get GarbageCollectorMXBean info ********************************/
List gcBeanList=ManagementFactory.getGarbageCollectorMXBeans();
int gcBeanSize=gcBeanList.size();
String gcNames[]=new String[gcBeanSize];
long gcCount[]=new long[gcBeanSize];
double gcTime[]=new double[gcBeanSize];
int gcLoop=0;
for(GarbageCollectorMXBean tempGCBean:gcBeanList) {
gcNames[gcLoop]=tempGCBean.getName();
gcCount[gcLoop]=tempGCBean.getCollectionCount();
gcTime[gcLoop]=tempGCBean.getCollectionTime()/1000.0;
gcLoop++;
}
/********************* get Stack Traces infos start *******************/
// Because tempThreadInfo.getStackTrace() don't return anything, I use this way
if(viewLockInfo) {
Map stackInfos=null;
stackInfos=Thread.getAllStackTraces();
for (Thread tempThread: stackInfos.keySet()) {
stackTraceMap.put(tempThread.getId(),stackInfos.get(tempThread));
}
}
/********************* get Stack Traces infos end *******************/
try {
boolean blockFlag=false;
for(long id : threadList) {
blockFlag=false;
printDataString.append("");
long tempThreadTime=tmxBean.getThreadCpuTime(id);
ThreadInfo tempThreadInfo=tmxBean.getThreadInfo(id);
String threadName=tempThreadInfo.getThreadName();
State threadState=tempThreadInfo.getThreadState();//.getLockedSynchronizers();
if(threadState==State.BLOCKED) {blocked++;
blockFlag=true;
} else if(threadState==State.NEW) {newthread++;
} else if(threadState==State.RUNNABLE) {runnable++;
} else if(threadState==State.TERMINATED) {terminated++;
} else if(threadState==State.TIMED_WAITING) {timed_waiting++;
} else if(threadState==State.WAITING){ waiting++;
}
//MonitorInfo[] mis=tempThreadInfo.getLockedMonitors();
int tempOrdinal=threadState.ordinal();
if(viewAllThreadInfo) {
//sb.append("
Ordinal="+tempOrdinal+" "+threadName+"=>"+threadState +" ThreadTime="+tempThreadTime);
printDataString.append("");
printDataString.append(tempOrdinal);
printDataString.append(" | ");
printDataString.append(threadName);
printDataString.append(" | ");
if(blockFlag) {
printDataString.append("");
printDataString.append("");
printDataString.append(threadState);
printDataString.append("");
} else {
printDataString.append(" | ");
printDataString.append(threadState);
}
printDataString.append(" | ");
printDataString.append(getTimeString(tempThreadTime));
printDataString.append(" | ");
if(viewLockInfo) {
printDataString.append("");
String lockOwnerName=tempThreadInfo.getLockOwnerName();
if(lockOwnerName!=null) {
printDataString.append(lockOwnerName);
lockOwnerSet.add(lockOwnerName);
} else {
printDataString.append(" ");
}
printDataString.append(" | ");
printDataString.append("");
StackTraceElement[] tempStackTraceElement =stackTraceMap.get(id);
int stackTraceSize=tempStackTraceElement.length;
if(stackTraceSize!=0) {
if(stackTraceSize<=stackTraceNumber) {
for (StackTraceElement line: tempStackTraceElement) {
printDataString.append(line).append(" ");
}
} else{
for(int loop=0;loop");
}
}
} else {
printDataString.append(" ");
}
printDataString.append(" | ");
}
}
printDataString.append("
\n");
}
printDataString.append("
");
out.flush();
//Thread.sleep(periodMillis);
} catch(Exception e) {
e.printStackTrace();
}
MemoryMXBean mbean = ManagementFactory.getMemoryMXBean();
MemoryUsage heapMem=mbean.getHeapMemoryUsage();
MemoryUsage nonHeapMem=mbean.getNonHeapMemoryUsage();
String heapInit=getMemoryString(heapMem.getInit());
String heapUsed=getMemoryString(heapMem.getUsed());
String heapMax=getMemoryString(heapMem.getMax());
String heapCommitted=getMemoryString(heapMem.getCommitted());
/*************************** Data Collect end *******************/
%>
Total Started Thread Count |
<%=tmxBean.getTotalStartedThreadCount()%> |
Peak Thread Count |
<%=tmxBean.getPeakThreadCount()%> |
Current Thread Count |
<%=tmxBean.getThreadCount() %> |
Daemon Thread Count |
<%= tmxBean.getDaemonThreadCount() %> |
<% for(int loop=0;loop
GC Name |
<%=gcNames[loop]%> |
GC Count |
<%=gcCount[loop]%> |
GC Time |
<%=gcTime[loop] %> sec |
Average GC Time |
<%=gcTime[loop]/gcCount[loop] * 1000 %> ms |
<% } %>
Heap Used |
<%=heapUsed%> |
Heap Min |
<%=heapInit%> |
Heap Max |
<%=heapMax %> |
Heap Committed |
<%= heapCommitted %> |
Thread State |
No. of state |
Description |
NEW |
<%=newthread %> |
A thread that has not yet started is in this state. |
RUNNABLE |
<%=runnable%> |
A thread executing in the Java virtual machine is in this state. |
BLOCKED |
<%=blocked%> |
A thread that is blocked waiting for a monitor lock is in this state. |
WAITING |
<%=waiting%> |
A thread that is waiting indefinitely for another thread to perform a particular action is in this state. |
TIMED_WAITING |
<%=timed_waiting%> |
A thread that is waiting for another thread to perform an action for up to a specified waiting time is in this state. |
TERMINATED |
<%=terminated%> |
A thread that has exited is in this state. |
<%
if(viewAllThreadInfo) {
if(lockOwnerSet.size()!=0) {
out.println("* Current Lock Owner List
");
out.println("");
for(String tempOwnerName:lockOwnerSet) {
out.println(" "+tempOwnerName+" | ");
}
out.println("
");
}
%>
* All Thread infos
<%
out.println(printDataString.toString());
}
%>
Copyright Sangmin, Lee. http://www.tuning-java.com All rights Reserved