1 36 37 58 import java.lang.management.*; 59 import javax.management.*; 60 import javax.management.remote.*; 61 import java.io.IOException ; 62 import java.util.ArrayList ; 63 import java.util.Collections ; 64 import java.util.List ; 65 import java.util.Map ; 66 import java.util.Map.Entry; 67 import java.util.Set ; 68 import java.util.SortedMap ; 69 import java.util.Timer ; 70 import java.util.TimerTask ; 71 import java.util.TreeMap ; 72 import java.util.concurrent.ExecutionException ; 73 import java.text.NumberFormat ; 74 import java.net.MalformedURLException ; 75 import static java.lang.management.ManagementFactory .*; 76 77 import java.awt.*; 78 import java.awt.event.*; 79 import javax.swing.*; 80 import javax.swing.border.*; 81 import javax.swing.event.*; 82 import javax.swing.table.*; 83 84 88 public class JTop extends JPanel { 89 private MBeanServerConnection server; 90 private ThreadMXBean tmbean; 91 private MyTableModel tmodel; 92 public JTop() { 93 super(new GridLayout(1,0)); 94 95 tmodel = new MyTableModel(); 96 JTable table = new JTable(tmodel); 97 table.setPreferredScrollableViewportSize(new Dimension(500, 300)); 98 99 table.setDefaultRenderer(Double .class, new DoubleRenderer()); 101 table.setIntercellSpacing(new Dimension(6,3)); 103 table.setRowHeight(table.getRowHeight() + 4); 104 105 JScrollPane scrollPane = new JScrollPane(table); 107 108 add(scrollPane); 110 } 111 112 public void setMBeanServerConnection(MBeanServerConnection mbs) { 115 this.server = mbs; 116 try { 117 this.tmbean = newPlatformMXBeanProxy(server, 118 THREAD_MXBEAN_NAME, 119 ThreadMXBean.class); 120 } catch (IOException e) { 121 e.printStackTrace(); 122 } 123 if (!tmbean.isThreadCpuTimeSupported()) { 124 System.err.println("This VM does not support thread CPU time monitoring"); 125 } else { 126 tmbean.setThreadCpuTimeEnabled(true); 127 } 128 } 129 130 class MyTableModel extends AbstractTableModel { 131 private String [] columnNames = {"ThreadName", 132 "CPU(sec)", 133 "State"}; 134 private List <Map.Entry <Long , ThreadInfo>> threadList = 137 Collections.EMPTY_LIST; 138 139 public MyTableModel() { 140 } 141 142 public int getColumnCount() { 143 return columnNames.length; 144 } 145 146 public int getRowCount() { 147 return threadList.size(); 148 } 149 150 public String getColumnName(int col) { 151 return columnNames[col]; 152 } 153 154 public Object getValueAt(int row, int col) { 155 Map.Entry <Long , ThreadInfo> me = threadList.get(row); 156 switch (col) { 157 case 0 : 158 return me.getValue().getThreadName(); 160 case 1 : 161 long ns = me.getKey().longValue(); 163 double sec = ns / 1000000000; 164 return new Double (sec); 165 case 2 : 166 return me.getValue().getThreadState(); 168 default: 169 return null; 170 } 171 } 172 173 public Class getColumnClass(int c) { 174 return getValueAt(0, c).getClass(); 175 } 176 177 void setThreadList(List <Map.Entry <Long , ThreadInfo>> list) { 178 threadList = list; 179 } 180 } 181 182 186 private List <Map.Entry <Long , ThreadInfo>> getThreadList() { 187 long[] tids = tmbean.getAllThreadIds(); 190 ThreadInfo[] tinfos = tmbean.getThreadInfo(tids); 191 192 SortedMap <Long , ThreadInfo> map = new TreeMap <Long , ThreadInfo>(); 194 for (int i = 0; i < tids.length; i++) { 195 long cpuTime = tmbean.getThreadCpuTime(tids[i]); 196 if (cpuTime != -1 && tinfos[i] != null) { 198 map.put(new Long (cpuTime), tinfos[i]); 199 } 200 } 201 202 Set <Map.Entry <Long , ThreadInfo>> set = map.entrySet(); 205 List <Map.Entry <Long , ThreadInfo>> list = 206 new ArrayList <Map.Entry <Long , ThreadInfo>>(set); 207 Collections.reverse(list); 208 return list; 209 } 210 211 212 215 class DoubleRenderer extends DefaultTableCellRenderer { 216 NumberFormat formatter; 217 public DoubleRenderer() { 218 super(); 219 setHorizontalAlignment(JLabel.RIGHT); 220 } 221 222 public void setValue(Object value) { 223 if (formatter==null) { 224 formatter = NumberFormat.getInstance(); 225 formatter.setMinimumFractionDigits(4); 226 } 227 setText((value == null) ? "" : formatter.format(value)); 228 } 229 } 230 231 class Worker extends SwingWorker<List <Map.Entry <Long , ThreadInfo>>,Object > { 241 private MyTableModel tmodel; 242 Worker(MyTableModel tmodel) { 243 this.tmodel = tmodel; 244 } 245 246 public List <Map.Entry <Long , ThreadInfo>> doInBackground() { 248 return getThreadList(); 249 } 250 251 protected void done() { 254 try { 255 tmodel.setThreadList(get()); 257 tmodel.fireTableDataChanged(); 259 } catch (InterruptedException e) { 260 } catch (ExecutionException e) { 261 } 262 } 263 } 264 265 public SwingWorker<?,?> newSwingWorker() { 267 return new Worker(tmodel); 268 } 269 270 public static void main(String [] args) throws Exception { 271 if (args.length != 1) { 273 usage(); 274 } 275 276 String [] arg2 = args[0].split(":"); 277 if (arg2.length != 2) { 278 usage(); 279 } 280 String hostname = arg2[0]; 281 int port = -1; 282 try { 283 port = Integer.parseInt(arg2[1]); 284 } catch (NumberFormatException x) { 285 usage(); 286 } 287 if (port < 0) { 288 usage(); 289 } 290 291 final JTop jtop = new JTop(); 293 MBeanServerConnection server = connect(hostname, port); 295 jtop.setMBeanServerConnection(server); 296 297 TimerTask timerTask = new TimerTask () { 299 public void run() { 300 jtop.newSwingWorker().execute(); 302 } 303 }; 304 305 SwingUtilities.invokeAndWait(new Runnable () { 308 public void run() { 309 createAndShowGUI(jtop); 310 } 311 }); 312 313 Timer timer = new Timer ("JTop Sampling thread"); 315 timer.schedule(timerTask, 0, 2000); 316 317 } 318 319 private static MBeanServerConnection connect(String hostname, int port) { 327 String urlPath = "/jndi/rmi://" + hostname + ":" + port + "/jmxrmi"; 330 MBeanServerConnection server = null; 331 try { 332 JMXServiceURL url = new JMXServiceURL("rmi", "", 0, urlPath); 333 JMXConnector jmxc = JMXConnectorFactory.connect(url); 334 server = jmxc.getMBeanServerConnection(); 335 } catch (MalformedURLException e) { 336 } catch (IOException e) { 338 System.err.println("\nCommunication error: " + e.getMessage()); 339 System.exit(1); 340 } 341 return server; 342 } 343 344 private static void usage() { 345 System.out.println("Usage: java JTop <hostname>:<port>"); 346 System.exit(1); 347 } 348 353 private static void createAndShowGUI(JPanel jtop) { 354 JFrame frame = new JFrame("JTop"); 356 frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); 357 358 JComponent contentPane = (JComponent) frame.getContentPane(); 360 contentPane.add(jtop, BorderLayout.CENTER); 361 contentPane.setOpaque(true); contentPane.setBorder(new EmptyBorder(12, 12, 12, 12)); 363 frame.setContentPane(contentPane); 364 365 frame.pack(); 367 frame.setVisible(true); 368 } 369 370 } 371 | Popular Tags |