21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package sun.tools.jconsole;
27
28 import java.awt.*;
29 import java.awt.event.*;
30 import java.io.*;
31 import java.lang.management.*;
32 import java.lang.reflect.*;
33 import java.util.*;
34 import java.util.concurrent.*;
35
36 import javax.accessibility.*;
37 import javax.management.*;
38 import javax.management.openmbean.CompositeData;
39 import javax.swing.*;
40 import javax.swing.border.*;
41 import javax.swing.text.*;
42
43 import sun.management.*;
44
45 import static sun.tools.jconsole.Formatter.*;
46 import static sun.tools.jconsole.OverviewPanel.*;
47 import static sun.tools.jconsole.Resources.*;
48 import static sun.tools.jconsole.Utilities.*;
49
50 @SuppressWarnings("serial")
51 class MemoryTab extends Tab implements ActionListener, ItemListener {
52 JComboBox plotterChoice;
53 TimeComboBox timeComboBox;
54 JButton gcButton;
55
56 PlotterPanel plotterPanel;
57 JPanel bottomPanel;
58 HTMLPane details;
59 PoolChart poolChart;
60
61 ArrayList<Plotter> plotterList;
62 Plotter heapPlotter, nonHeapPlotter;
63
64 private MemoryOverviewPanel overviewPanel;
65
66 private static final String usedKey = "used";
67 private static final String committedKey = "committed";
68 private static final String maxKey = "max";
69 private static final String thresholdKey = "threshold";
70
71 private static final String usedName = Resources.getText("Used");
72 private static final String committedName = Resources.getText("Committed");
73 private static final String maxName = Resources.getText("Max");
74 private static final String thresholdName = Resources.getText("Threshold");
75
76 private static final Color usedColor = Plotter.defaultColor;
77 private static final Color committedColor = null;
78 private static final Color maxColor = null;
79 private static final Color thresholdColor = Color.red;
80
81 private static final String infoLabelFormat = "MemoryTab.infoLabelFormat";
82
83 /*
84 Hierarchy of panels and layouts for this tab:
85
86 MemoryTab (BorderLayout)
87
88 North: topPanel (BorderLayout)
89
90 Center: controlPanel (FlowLayout)
91 plotterChoice, timeComboBox
92
93 East: topRightPanel (FlowLayout)
94 gcButton
95
96 Center: plotterPanel
97
98 Center: plotter
99
100 South: bottomPanel (BorderLayout)
101
102 Center: details
103 East: poolChart
104 */
105
106
107 public static String getTabName() {
108 return getText("Memory");
109 }
110
111 public MemoryTab(VMPanel vmPanel) {
112 super(vmPanel, getTabName());
113
114 setLayout(new BorderLayout(0, 0));
115 setBorder(new EmptyBorder(4, 4, 3, 4));
116
117 JPanel topPanel = new JPanel(new BorderLayout());
118 plotterPanel = new PlotterPanel(null);
119 bottomPanel = new JPanel(new BorderLayout());
120
121 add(topPanel, BorderLayout.NORTH);
122 add(plotterPanel, BorderLayout.CENTER);
123
124 JPanel controlPanel = new JPanel(new FlowLayout(FlowLayout.LEADING, 20, 5));
125 topPanel.add(controlPanel, BorderLayout.CENTER);
126
127 // Plotter choice
128 plotterChoice = new JComboBox();
129 plotterChoice.addItemListener(this);
130 controlPanel.add(new LabeledComponent(getText("Chart:"),
131 getMnemonicInt("Chart:"),
132 plotterChoice));
133
134 // Range control
135 timeComboBox = new TimeComboBox();
136 controlPanel.add(new LabeledComponent(getText("Time Range:"),
137 getMnemonicInt("Time Range:"),
138 timeComboBox));
139
140 gcButton = new JButton(getText("Perform GC"));
141 gcButton.setMnemonic(getMnemonicInt("Perform GC"));
142 gcButton.addActionListener(this);
143 gcButton.setToolTipText(getText("Perform GC.toolTip"));
144 JPanel topRightPanel = new JPanel();
145 topRightPanel.setBorder(new EmptyBorder(0, 65-8, 0, 70));
146 topRightPanel.add(gcButton);
147 topPanel.add(topRightPanel, BorderLayout.AFTER_LINE_ENDS);
148
149 bottomPanel.setBorder(new CompoundBorder(new TitledBorder(getText("Details")),
150 new EmptyBorder(10, 10, 10, 10)));
151
152 details = new HTMLPane();
153 setAccessibleName(details, getText("Details"));
154 bottomPanel.add(new JScrollPane(details), BorderLayout.CENTER);
155
156 poolChart = new PoolChart();
157 bottomPanel.add(poolChart, BorderLayout.AFTER_LINE_ENDS);
158 }
159
160
161 private void createPlotters() throws IOException {
162 plotterList = new ArrayList<Plotter>();
163
164 ProxyClient proxyClient = vmPanel.getProxyClient();
165
166 heapPlotter = new Plotter(Plotter.Unit.BYTES) {
167 public String toString() {
168 return Resources.getText("Heap Memory Usage");
169 }
170 };
171 proxyClient.addWeakPropertyChangeListener(heapPlotter);
172
173 nonHeapPlotter = new Plotter(Plotter.Unit.BYTES) {
174 public String toString() {
175 return Resources.getText("Non-Heap Memory Usage");
176 }
177 };
178
179 setAccessibleName(heapPlotter,
180 getText("MemoryTab.heapPlotter.accessibleName"));
181 setAccessibleName(nonHeapPlotter,
182 getText("MemoryTab.nonHeapPlotter.accessibleName"));
183
184 proxyClient.addWeakPropertyChangeListener(nonHeapPlotter);
185
186 heapPlotter.createSequence(usedKey, usedName, usedColor, true);
187 heapPlotter.createSequence(committedKey, committedName, committedColor, false);
188 heapPlotter.createSequence(maxKey, maxName, maxColor, false);
189
190 nonHeapPlotter.createSequence(usedKey, usedName, usedColor, true);
191 nonHeapPlotter.createSequence(committedKey, committedName, committedColor, false);
192 nonHeapPlotter.createSequence(maxKey, maxName, maxColor, false);
193
194 plotterList.add(heapPlotter);
195 plotterList.add(nonHeapPlotter);
196
197 // Now add memory pools
198 Map<ObjectName, MBeanInfo> mBeanMap = proxyClient.getMBeans("java.lang");
199 Set<ObjectName> keys = mBeanMap.keySet();
200 ObjectName[] objectNames = keys.toArray(new ObjectName[keys.size()]);
201 ArrayList<PoolPlotter> nonHeapPlotters = new ArrayList<PoolPlotter>(2);
202 for (ObjectName objectName : objectNames) {
203 String type = objectName.getKeyProperty("type");
204 if (type.equals("MemoryPool")) {
205 String name = getText("MemoryPoolLabel",
206 objectName.getKeyProperty("name"));
207 // Heap or non-heap?
208 boolean isHeap = false;
209 AttributeList al =
210 proxyClient.getAttributes(objectName,
211 new String[] { "Type" });
212 if (al.size() > 0) {
213 isHeap = MemoryType.HEAP.name().equals(((Attribute)al.get(0)).getValue());
214 }
215 PoolPlotter poolPlotter = new PoolPlotter(objectName, name, isHeap);
216 proxyClient.addWeakPropertyChangeListener(poolPlotter);
217
218 poolPlotter.createSequence(usedKey, usedName, usedColor, true);
219 poolPlotter.createSequence(committedKey, committedName, committedColor, false);
220 poolPlotter.createSequence(maxKey, maxName, maxColor, false);
221 poolPlotter.createSequence(thresholdKey, thresholdName, thresholdColor, false);
222 poolPlotter.setUseDashedTransitions(thresholdKey, true);
223
224 if (isHeap) {
225 plotterList.add(poolPlotter);
226 } else {
227 // Will be added to plotterList below
228 nonHeapPlotters.add(poolPlotter);
229 }
230 }
231 }
232 // Add non-heap plotters last
233 for (PoolPlotter poolPlotter : nonHeapPlotters) {
234 plotterList.add(poolPlotter);
235 }
236 }
237
238
239 public void itemStateChanged(ItemEvent ev) {
240 if (ev.getStateChange() == ItemEvent.SELECTED) {
241 Plotter plotter = (Plotter)plotterChoice.getSelectedItem();
269 ProxyClient proxyClient = vmPanel.getProxyClient();
270
271 if (plotterList == null) {
272 try {
273 createPlotters();
274 } catch (UndeclaredThrowableException e) {
275 proxyClient.markAsDead();
276 return false;
277 } catch (final IOException ex) {
278 return false;
279 }
280 initialRun = true;
281 }
282
283 int n = plotterList.size();
284 used = new long[n];
285 committed = new long[n];
286 max = new long[n];
287 threshold = new long[n];
288 timeStamp = System.currentTimeMillis();
289 int poolCount = 0;
290
291 for (int i = 0; i < n; i++) {
292 Plotter plotter = plotterList.get(i);
293 MemoryUsage mu = null;
294 used[i] = -1L;
295 threshold[i] = -1L;
296
297 try {
298 if (plotter instanceof PoolPlotter) {
299 PoolPlotter poolPlotter = (PoolPlotter)plotter;
300 ObjectName objectName = poolPlotter.objectName;
301 AttributeList al =
302 proxyClient.getAttributes(objectName,
303 new String[] { "Usage", "UsageThreshold" });
304 if (al.size() > 0) {
305 CompositeData cd = (CompositeData)((Attribute)al.get(0)).getValue();
306 mu = MemoryUsage.from(cd);
307
308 if (al.size() > 1) {
309 threshold[i] = (Long)((Attribute)al.get(1)).getValue();
383 }
384 };
385 }
386
387 private String formatDetails() {
388 ProxyClient proxyClient = vmPanel.getProxyClient();
389 if (proxyClient.isDead()) {
390 return "";
391 }
392
393 String text = "<table cellspacing=0 cellpadding=0>";
394
395 Plotter plotter = (Plotter)plotterChoice.getSelectedItem();
396 if (plotter == null) {
397 return "";
398 }
399
400 //long time = plotter.getLastTimeStamp();
401 long time = System.currentTimeMillis();
402 String timeStamp = formatDateTime(time);
403 text += newRow(getText("Time"), timeStamp);
404
405 long used = plotter.getLastValue(usedKey);
406 long committed = plotter.getLastValue(committedKey);
407 long max = plotter.getLastValue(maxKey);
408 long threshold = plotter.getLastValue(thresholdKey);
409
410 text += newRow(getText("Used"), formatKBytes(used));
411 if (committed > 0L) {
412 text += newRow(getText("Committed"), formatKBytes(committed));
413 }
414 if (max > 0L) {
415 text += newRow(getText("Max"), formatKBytes(max));
416 }
417 if (threshold > 0L) {
418 text += newRow(getText("Usage Threshold"), formatKBytes(threshold));
419 }
420
421 try {
422 Collection<GarbageCollectorMXBean> garbageCollectors =
423 proxyClient.getGarbageCollectorMXBeans();
424
425 boolean descPrinted = false;
426 for (GarbageCollectorMXBean garbageCollectorMBean : garbageCollectors) {
427 String gcName = garbageCollectorMBean.getName();
428 long gcCount = garbageCollectorMBean.getCollectionCount();
429 long gcTime = garbageCollectorMBean.getCollectionTime();
430 String str = getText("GC time details", justify(formatTime(gcTime), 14),
431 gcName,
432 String.format("%,d",gcCount));
433 if (!descPrinted) {
434 text += newRow(getText("GC time"), str);
435 descPrinted = true;
436 } else {
437 text += newRow(null, str);
438 }
439 }
440 } catch (IOException e) {
441 }
442
443 return text;
444 }
445
446 public void actionPerformed(ActionEvent ev) {
447 Object src = ev.getSource();
448 if (src == gcButton) {
449 gc();
450 }
451 }
452
453 private class PoolPlotter extends Plotter {
454 ObjectName objectName;
455 String name;
456 boolean isHeap;
457 long value, threshold, max;
458 int barX;
459
460 public PoolPlotter(ObjectName objectName, String name, boolean isHeap) {
461 super(Plotter.Unit.BYTES);
462
463 this.objectName = objectName;
464 this.name = name;
465 this.isHeap = isHeap;
466
467 setAccessibleName(this,
468 getText("MemoryTab.poolPlotter.accessibleName",
469 name));
470 }
471
472
473 public String toString() {
474 return name;
475 }
476 }
477
478 private class PoolChart extends BorderedComponent
479 implements Accessible, MouseListener {
480 final int height = 150;
481 final int leftMargin = 50;
482 final int rightMargin = 23;
483 final int bottomMargin = 35;
484 final int barWidth = 22;
485 final int barGap = 3;
486 final int groupGap = 8;
487 final int barHeight = height * 2 / 3;
488
610 g.drawRect(nonHeapRect.x, nonHeapRect.y, nonHeapRect.width, nonHeapRect.height);
611
612 Color heapColor = greenBar;
613 Color nonHeapColor = greenBar;
614
615
616 for (PoolPlotter poolPlotter : poolPlotters) {
617 if (poolPlotter.threshold > 0L && poolPlotter.value > poolPlotter.threshold) {
618 if (poolPlotter.isHeap) {
619 heapColor = thresholdColor;
620 } else {
621 nonHeapColor = thresholdColor;
622 }
623 }
624 }
625 g.setColor(heapColor);
626 g.fillRect(heapRect.x + 1, heapRect.y + 1, heapRect.width - 1, heapRect.height - 1);
627 g.setColor(nonHeapColor);
628 g.fillRect(nonHeapRect.x + 1, nonHeapRect.y + 1, nonHeapRect.width - 1, nonHeapRect.height - 1);
629
630 String str = getText("Heap");
631 int stringWidth = fm.stringWidth(str);
632 int x = heapRect.x + (heapRect.width - stringWidth) / 2;
633 int y = heapRect.y + heapRect.height - 6;
634 g.setColor(Color.white);
635 g.drawString(str, x-1, y-1);
636 g.drawString(str, x+1, y-1);
637 g.drawString(str, x-1, y+1);
638 g.drawString(str, x+1, y+1);
639 g.setColor(Color.black);
640 g.drawString(str, x, y);
641
642 str = getText("Non-Heap");
643 stringWidth = fm.stringWidth(str);
644 x = nonHeapRect.x + (nonHeapRect.width - stringWidth) / 2;
645 y = nonHeapRect.y + nonHeapRect.height - 6;
646 g.setColor(Color.white);
647 g.drawString(str, x-1, y-1);
648 g.drawString(str, x+1, y-1);
649 g.drawString(str, x-1, y+1);
650 g.drawString(str, x+1, y+1);
651 g.setColor(Color.black);
652 g.drawString(str, x, y);
653
654 // Highlight current plotter
655 g.setColor(Color.blue);
656 r = null;
657 Plotter plotter = (Plotter)plotterChoice.getSelectedItem();
658 if (plotter == heapPlotter) {
659 r = heapRect;
660 } else if (plotter == nonHeapPlotter) {
661 r = nonHeapRect;
662 } else if (plotter instanceof PoolPlotter) {
711 }
712 }
713 return plotter;
714 }
715
716 public void mousePressed(MouseEvent e) {}
717 public void mouseReleased(MouseEvent e) {}
718 public void mouseEntered(MouseEvent e) {}
719 public void mouseExited(MouseEvent e) {}
720
721
722 public AccessibleContext getAccessibleContext() {
723 if (accessibleContext == null) {
724 accessibleContext = new AccessiblePoolChart();
725 }
726 return accessibleContext;
727 }
728
729 protected class AccessiblePoolChart extends AccessibleJPanel {
730 public String getAccessibleName() {
731 String name = getText("MemoryTab.poolChart.accessibleName");
732
733 String keyValueList = "";
734 for (PoolPlotter poolPlotter : poolPlotters) {
735 String value = (poolPlotter.value * 100 / poolPlotter.max) + "%";
736 // Assume format string ends with newline
737 keyValueList +=
738 getText("Plotter.accessibleName.keyAndValue",
739 poolPlotter.toString(), value);
740 if (poolPlotter.threshold > 0L) {
741 String threshold =
742 (poolPlotter.threshold * 100 / poolPlotter.max) + "%";
743 if (poolPlotter.value > poolPlotter.threshold) {
744 keyValueList +=
745 getText("MemoryTab.poolChart.aboveThreshold",
746 threshold);
747 } else {
748 keyValueList +=
749 getText("MemoryTab.poolChart.belowThreshold",
750 threshold);
751 }
752 }
753 }
754
755 return name + "\n" + keyValueList + ".";
756 }
757 }
758 }
759
760
761 OverviewPanel[] getOverviewPanels() {
762 if (overviewPanel == null) {
763 overviewPanel = new MemoryOverviewPanel();
764 }
765 return new OverviewPanel[] { overviewPanel };
766 }
767
768 private static class MemoryOverviewPanel extends OverviewPanel {
769 MemoryOverviewPanel() {
770 super(getText("Heap Memory Usage"), usedKey, usedName, Plotter.Unit.BYTES);
771 }
772
773 private void updateMemoryInfo(long used, long committed, long max) {
774 getInfoLabel().setText(getText(infoLabelFormat,
775 formatBytes(used, true),
776 formatBytes(committed, true),
777 formatBytes(max, true)));
778 }
779 }
780 }
|
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package sun.tools.jconsole;
27
28 import java.awt.*;
29 import java.awt.event.*;
30 import java.io.*;
31 import java.lang.management.*;
32 import java.lang.reflect.*;
33 import java.util.*;
34 import java.util.concurrent.*;
35
36 import javax.accessibility.*;
37 import javax.management.*;
38 import javax.management.openmbean.CompositeData;
39 import javax.swing.*;
40 import javax.swing.border.*;
41
42 import sun.tools.jconsole.resources.Messages;
43
44 import static sun.tools.jconsole.Formatter.*;
45 import static sun.tools.jconsole.Utilities.*;
46
47 @SuppressWarnings("serial")
48 class MemoryTab extends Tab implements ActionListener, ItemListener {
49 JComboBox<Plotter> plotterChoice;
50 TimeComboBox timeComboBox;
51 JButton gcButton;
52
53 PlotterPanel plotterPanel;
54 JPanel bottomPanel;
55 HTMLPane details;
56 PoolChart poolChart;
57
58 ArrayList<Plotter> plotterList;
59 Plotter heapPlotter, nonHeapPlotter;
60
61 private MemoryOverviewPanel overviewPanel;
62
63 private static final String usedKey = "used";
64 private static final String committedKey = "committed";
65 private static final String maxKey = "max";
66 private static final String thresholdKey = "threshold";
67 private static final Color usedColor = Plotter.defaultColor;
68 private static final Color committedColor = null;
69 private static final Color maxColor = null;
70 private static final Color thresholdColor = Color.red;
71
72 /*
73 Hierarchy of panels and layouts for this tab:
74
75 MemoryTab (BorderLayout)
76
77 North: topPanel (BorderLayout)
78
79 Center: controlPanel (FlowLayout)
80 plotterChoice, timeComboBox
81
82 East: topRightPanel (FlowLayout)
83 gcButton
84
85 Center: plotterPanel
86
87 Center: plotter
88
89 South: bottomPanel (BorderLayout)
90
91 Center: details
92 East: poolChart
93 */
94
95
96 public static String getTabName() {
97 return Messages.MEMORY;
98 }
99
100 public MemoryTab(VMPanel vmPanel) {
101 super(vmPanel, getTabName());
102
103 setLayout(new BorderLayout(0, 0));
104 setBorder(new EmptyBorder(4, 4, 3, 4));
105
106 JPanel topPanel = new JPanel(new BorderLayout());
107 plotterPanel = new PlotterPanel(null);
108 bottomPanel = new JPanel(new BorderLayout());
109
110 add(topPanel, BorderLayout.NORTH);
111 add(plotterPanel, BorderLayout.CENTER);
112
113 JPanel controlPanel = new JPanel(new FlowLayout(FlowLayout.LEADING, 20, 5));
114 topPanel.add(controlPanel, BorderLayout.CENTER);
115
116 // Plotter choice
117 plotterChoice = new JComboBox<Plotter>();
118 plotterChoice.addItemListener(this);
119 controlPanel.add(new LabeledComponent(Messages.CHART_COLON,
120 Resources.getMnemonicInt(Messages.CHART_COLON),
121 plotterChoice));
122
123 // Range control
124 timeComboBox = new TimeComboBox();
125 controlPanel.add(new LabeledComponent(Messages.TIME_RANGE_COLON,
126 Resources.getMnemonicInt(Messages.TIME_RANGE_COLON),
127 timeComboBox));
128
129 gcButton = new JButton(Messages.PERFORM_GC);
130 gcButton.setMnemonic(Resources.getMnemonicInt(Messages.PERFORM_GC));
131 gcButton.addActionListener(this);
132 gcButton.setToolTipText(Messages.PERFORM_GC_TOOLTIP);
133 JPanel topRightPanel = new JPanel();
134 topRightPanel.setBorder(new EmptyBorder(0, 65-8, 0, 70));
135 topRightPanel.add(gcButton);
136 topPanel.add(topRightPanel, BorderLayout.AFTER_LINE_ENDS);
137
138 bottomPanel.setBorder(new CompoundBorder(new TitledBorder(Messages.DETAILS),
139 new EmptyBorder(10, 10, 10, 10)));
140
141 details = new HTMLPane();
142 setAccessibleName(details, Messages.DETAILS);
143 bottomPanel.add(new JScrollPane(details), BorderLayout.CENTER);
144
145 poolChart = new PoolChart();
146 bottomPanel.add(poolChart, BorderLayout.AFTER_LINE_ENDS);
147 }
148
149
150 private void createPlotters() throws IOException {
151 plotterList = new ArrayList<Plotter>();
152
153 ProxyClient proxyClient = vmPanel.getProxyClient();
154
155 heapPlotter = new Plotter(Plotter.Unit.BYTES) {
156 public String toString() {
157 return Messages.HEAP_MEMORY_USAGE;
158 }
159 };
160 proxyClient.addWeakPropertyChangeListener(heapPlotter);
161
162 nonHeapPlotter = new Plotter(Plotter.Unit.BYTES) {
163 public String toString() {
164 return Messages.NON_HEAP_MEMORY_USAGE;
165 }
166 };
167
168 setAccessibleName(heapPlotter,
169 Messages.MEMORY_TAB_HEAP_PLOTTER_ACCESSIBLE_NAME);
170 setAccessibleName(nonHeapPlotter,
171 Messages.MEMORY_TAB_NON_HEAP_PLOTTER_ACCESSIBLE_NAME);
172
173 proxyClient.addWeakPropertyChangeListener(nonHeapPlotter);
174
175 heapPlotter.createSequence(usedKey, Messages.USED, usedColor, true);
176 heapPlotter.createSequence(committedKey, Messages.COMMITTED, committedColor, false);
177 heapPlotter.createSequence(maxKey, Messages.MAX, maxColor, false);
178
179 nonHeapPlotter.createSequence(usedKey, Messages.USED, usedColor, true);
180 nonHeapPlotter.createSequence(committedKey, Messages.COMMITTED, committedColor, false);
181 nonHeapPlotter.createSequence(maxKey, Messages.MAX, maxColor, false);
182
183 plotterList.add(heapPlotter);
184 plotterList.add(nonHeapPlotter);
185
186 // Now add memory pools
187 Map<ObjectName, MBeanInfo> mBeanMap = proxyClient.getMBeans("java.lang");
188 Set<ObjectName> keys = mBeanMap.keySet();
189 ObjectName[] objectNames = keys.toArray(new ObjectName[keys.size()]);
190 ArrayList<PoolPlotter> nonHeapPlotters = new ArrayList<PoolPlotter>(2);
191 for (ObjectName objectName : objectNames) {
192 String type = objectName.getKeyProperty("type");
193 if (type.equals("MemoryPool")) {
194 String name = Resources.format(Messages.MEMORY_POOL_LABEL,
195 objectName.getKeyProperty("name"));
196 // Heap or non-heap?
197 boolean isHeap = false;
198 AttributeList al =
199 proxyClient.getAttributes(objectName,
200 new String[] { "Type" });
201 if (al.size() > 0) {
202 isHeap = MemoryType.HEAP.name().equals(((Attribute)al.get(0)).getValue());
203 }
204 PoolPlotter poolPlotter = new PoolPlotter(objectName, name, isHeap);
205 proxyClient.addWeakPropertyChangeListener(poolPlotter);
206
207 poolPlotter.createSequence(usedKey, Messages.USED, usedColor, true);
208 poolPlotter.createSequence(committedKey, Messages.COMMITTED, committedColor, false);
209 poolPlotter.createSequence(maxKey, Messages.MAX, maxColor, false);
210 poolPlotter.createSequence(thresholdKey, Messages.THRESHOLD, thresholdColor, false);
211 poolPlotter.setUseDashedTransitions(thresholdKey, true);
212
213 if (isHeap) {
214 plotterList.add(poolPlotter);
215 } else {
216 // Will be added to plotterList below
217 nonHeapPlotters.add(poolPlotter);
218 }
219 }
220 }
221 // Add non-heap plotters last
222 for (PoolPlotter poolPlotter : nonHeapPlotters) {
223 plotterList.add(poolPlotter);
224 }
225 }
226
227
228 public void itemStateChanged(ItemEvent ev) {
229 if (ev.getStateChange() == ItemEvent.SELECTED) {
230 Plotter plotter = (Plotter)plotterChoice.getSelectedItem();
258 ProxyClient proxyClient = vmPanel.getProxyClient();
259
260 if (plotterList == null) {
261 try {
262 createPlotters();
263 } catch (UndeclaredThrowableException e) {
264 proxyClient.markAsDead();
265 return false;
266 } catch (final IOException ex) {
267 return false;
268 }
269 initialRun = true;
270 }
271
272 int n = plotterList.size();
273 used = new long[n];
274 committed = new long[n];
275 max = new long[n];
276 threshold = new long[n];
277 timeStamp = System.currentTimeMillis();
278
279 for (int i = 0; i < n; i++) {
280 Plotter plotter = plotterList.get(i);
281 MemoryUsage mu = null;
282 used[i] = -1L;
283 threshold[i] = -1L;
284
285 try {
286 if (plotter instanceof PoolPlotter) {
287 PoolPlotter poolPlotter = (PoolPlotter)plotter;
288 ObjectName objectName = poolPlotter.objectName;
289 AttributeList al =
290 proxyClient.getAttributes(objectName,
291 new String[] { "Usage", "UsageThreshold" });
292 if (al.size() > 0) {
293 CompositeData cd = (CompositeData)((Attribute)al.get(0)).getValue();
294 mu = MemoryUsage.from(cd);
295
296 if (al.size() > 1) {
297 threshold[i] = (Long)((Attribute)al.get(1)).getValue();
371 }
372 };
373 }
374
375 private String formatDetails() {
376 ProxyClient proxyClient = vmPanel.getProxyClient();
377 if (proxyClient.isDead()) {
378 return "";
379 }
380
381 String text = "<table cellspacing=0 cellpadding=0>";
382
383 Plotter plotter = (Plotter)plotterChoice.getSelectedItem();
384 if (plotter == null) {
385 return "";
386 }
387
388 //long time = plotter.getLastTimeStamp();
389 long time = System.currentTimeMillis();
390 String timeStamp = formatDateTime(time);
391 text += newRow(Messages.TIME, timeStamp);
392
393 long used = plotter.getLastValue(usedKey);
394 long committed = plotter.getLastValue(committedKey);
395 long max = plotter.getLastValue(maxKey);
396 long threshold = plotter.getLastValue(thresholdKey);
397
398 text += newRow(Messages.USED, formatKBytes(used));
399 if (committed > 0L) {
400 text += newRow(Messages.COMMITTED, formatKBytes(committed));
401 }
402 if (max > 0L) {
403 text += newRow(Messages.MAX, formatKBytes(max));
404 }
405 if (threshold > 0L) {
406 text += newRow(Messages.USAGE_THRESHOLD, formatKBytes(threshold));
407 }
408
409 try {
410 Collection<GarbageCollectorMXBean> garbageCollectors =
411 proxyClient.getGarbageCollectorMXBeans();
412
413 boolean descPrinted = false;
414 for (GarbageCollectorMXBean garbageCollectorMBean : garbageCollectors) {
415 String gcName = garbageCollectorMBean.getName();
416 long gcCount = garbageCollectorMBean.getCollectionCount();
417 long gcTime = garbageCollectorMBean.getCollectionTime();
418 String str = Resources.format(Messages.GC_TIME_DETAILS, justify(formatTime(gcTime), 14),
419 gcName,
420 String.format("%,d",gcCount));
421 if (!descPrinted) {
422 text += newRow(Messages.GC_TIME, str);
423 descPrinted = true;
424 } else {
425 text += newRow(null, str);
426 }
427 }
428 } catch (IOException e) {
429 }
430
431 return text;
432 }
433
434 public void actionPerformed(ActionEvent ev) {
435 Object src = ev.getSource();
436 if (src == gcButton) {
437 gc();
438 }
439 }
440
441 private class PoolPlotter extends Plotter {
442 ObjectName objectName;
443 String name;
444 boolean isHeap;
445 long value, threshold, max;
446 int barX;
447
448 public PoolPlotter(ObjectName objectName, String name, boolean isHeap) {
449 super(Plotter.Unit.BYTES);
450
451 this.objectName = objectName;
452 this.name = name;
453 this.isHeap = isHeap;
454
455 setAccessibleName(this,
456 Resources.format(Messages.MEMORY_TAB_POOL_PLOTTER_ACCESSIBLE_NAME,
457 name));
458 }
459
460
461 public String toString() {
462 return name;
463 }
464 }
465
466 private class PoolChart extends BorderedComponent
467 implements Accessible, MouseListener {
468 final int height = 150;
469 final int leftMargin = 50;
470 final int rightMargin = 23;
471 final int bottomMargin = 35;
472 final int barWidth = 22;
473 final int barGap = 3;
474 final int groupGap = 8;
475 final int barHeight = height * 2 / 3;
476
598 g.drawRect(nonHeapRect.x, nonHeapRect.y, nonHeapRect.width, nonHeapRect.height);
599
600 Color heapColor = greenBar;
601 Color nonHeapColor = greenBar;
602
603
604 for (PoolPlotter poolPlotter : poolPlotters) {
605 if (poolPlotter.threshold > 0L && poolPlotter.value > poolPlotter.threshold) {
606 if (poolPlotter.isHeap) {
607 heapColor = thresholdColor;
608 } else {
609 nonHeapColor = thresholdColor;
610 }
611 }
612 }
613 g.setColor(heapColor);
614 g.fillRect(heapRect.x + 1, heapRect.y + 1, heapRect.width - 1, heapRect.height - 1);
615 g.setColor(nonHeapColor);
616 g.fillRect(nonHeapRect.x + 1, nonHeapRect.y + 1, nonHeapRect.width - 1, nonHeapRect.height - 1);
617
618 String str = Messages.HEAP;
619 int stringWidth = fm.stringWidth(str);
620 int x = heapRect.x + (heapRect.width - stringWidth) / 2;
621 int y = heapRect.y + heapRect.height - 6;
622 g.setColor(Color.white);
623 g.drawString(str, x-1, y-1);
624 g.drawString(str, x+1, y-1);
625 g.drawString(str, x-1, y+1);
626 g.drawString(str, x+1, y+1);
627 g.setColor(Color.black);
628 g.drawString(str, x, y);
629
630 str = Messages.NON_HEAP;
631 stringWidth = fm.stringWidth(str);
632 x = nonHeapRect.x + (nonHeapRect.width - stringWidth) / 2;
633 y = nonHeapRect.y + nonHeapRect.height - 6;
634 g.setColor(Color.white);
635 g.drawString(str, x-1, y-1);
636 g.drawString(str, x+1, y-1);
637 g.drawString(str, x-1, y+1);
638 g.drawString(str, x+1, y+1);
639 g.setColor(Color.black);
640 g.drawString(str, x, y);
641
642 // Highlight current plotter
643 g.setColor(Color.blue);
644 r = null;
645 Plotter plotter = (Plotter)plotterChoice.getSelectedItem();
646 if (plotter == heapPlotter) {
647 r = heapRect;
648 } else if (plotter == nonHeapPlotter) {
649 r = nonHeapRect;
650 } else if (plotter instanceof PoolPlotter) {
699 }
700 }
701 return plotter;
702 }
703
704 public void mousePressed(MouseEvent e) {}
705 public void mouseReleased(MouseEvent e) {}
706 public void mouseEntered(MouseEvent e) {}
707 public void mouseExited(MouseEvent e) {}
708
709
710 public AccessibleContext getAccessibleContext() {
711 if (accessibleContext == null) {
712 accessibleContext = new AccessiblePoolChart();
713 }
714 return accessibleContext;
715 }
716
717 protected class AccessiblePoolChart extends AccessibleJPanel {
718 public String getAccessibleName() {
719 String name = Messages.MEMORY_TAB_POOL_CHART_ACCESSIBLE_NAME;
720
721 String keyValueList = "";
722 for (PoolPlotter poolPlotter : poolPlotters) {
723 String value = (poolPlotter.value * 100 / poolPlotter.max) + "%";
724 // Assume format string ends with newline
725 keyValueList +=
726 Resources.format(Messages.PLOTTER_ACCESSIBLE_NAME_KEY_AND_VALUE,
727 poolPlotter.toString(), value);
728 if (poolPlotter.threshold > 0L) {
729 String threshold =
730 (poolPlotter.threshold * 100 / poolPlotter.max) + "%";
731 if (poolPlotter.value > poolPlotter.threshold) {
732 keyValueList +=
733 Resources.format(Messages.MEMORY_TAB_POOL_CHART_ABOVE_THRESHOLD,
734 threshold);
735 } else {
736 keyValueList +=
737 Resources.format(Messages.MEMORY_TAB_POOL_CHART_BELOW_THRESHOLD,
738 threshold);
739 }
740 }
741 }
742
743 return name + "\n" + keyValueList + ".";
744 }
745 }
746 }
747
748
749 OverviewPanel[] getOverviewPanels() {
750 if (overviewPanel == null) {
751 overviewPanel = new MemoryOverviewPanel();
752 }
753 return new OverviewPanel[] { overviewPanel };
754 }
755
756 private static class MemoryOverviewPanel extends OverviewPanel {
757 MemoryOverviewPanel() {
758 super(Messages.HEAP_MEMORY_USAGE, usedKey, Messages.USED, Plotter.Unit.BYTES);
759 }
760
761 private void updateMemoryInfo(long used, long committed, long max) {
762 getInfoLabel().setText(Resources.format(Messages.MEMORY_TAB_INFO_LABEL_FORMAT,
763 formatBytes(used, true),
764 formatBytes(committed, true),
765 formatBytes(max, true)));
766 }
767 }
768 }
|