001: package tijmp.ui;
002:
003: import java.awt.BorderLayout;
004: import java.awt.EventQueue;
005: import java.awt.event.ActionEvent;
006: import java.awt.event.ActionListener;
007: import java.lang.management.MemoryMXBean;
008: import java.util.List;
009: import java.util.Map;
010: import javax.swing.BorderFactory;
011: import javax.swing.JButton;
012: import javax.swing.JComponent;
013: import javax.swing.JFrame;
014: import javax.swing.JLabel;
015: import javax.swing.JPanel;
016: import tijmp.HeapWalkEntry;
017: import tijmp.OwnerInfoHeader;
018: import tijmp.ProfilerHandler;
019: import tijmp.UIHandler;
020: import tijmp.actions.DefaultFilter;
021: import tijmp.actions.MemoryInfo;
022: import tijmp.filter.AcceptAllFilter;
023:
024: /** An ui handler that runs in the same jvm as the program
025: * being profiled and uses swing to present information.
026: */
027: public class InVMUI implements UIHandler {
028: private ProfilerHandler ph;
029: private JFrame frame;
030: private JLabel statusLabel;
031: private JButton gc;
032: private JButton heapWalker;
033: private long heapWalkStarted;
034: private FilterConfig fc;
035:
036: public void init(ProfilerHandler ph) {
037: this .ph = ph;
038: EventQueue.invokeLater(new Runnable() {
039: public void run() {
040: fc = new FilterConfig();
041: buildGui();
042: }
043: });
044: }
045:
046: public FilterConfig getFilterConfig() {
047: return fc;
048: }
049:
050: private void runGCOffEDT() {
051: ph.submitTask(new Runnable() {
052: public void run() {
053: ph.runGC();
054: gcFinished();
055: }
056: });
057: }
058:
059: private void walkHeapOffEDT() {
060: ph.submitTask(new Runnable() {
061: public void run() {
062: heapWalkStarted = System.currentTimeMillis();
063: ph.walkHeap();
064: }
065: });
066: }
067:
068: private void buildGui() {
069: frame = new JFrame("TIJMPController");
070: JPanel buttons = new JPanel();
071: gc = new JButton("GC");
072: gc.addActionListener(new ActionListener() {
073: public void actionPerformed(ActionEvent e) {
074: gc.setEnabled(false);
075: runGCOffEDT();
076: }
077: });
078: buttons.add(gc);
079: heapWalker = new JButton("Walk heap");
080: heapWalker.addActionListener(new ActionListener() {
081: public void actionPerformed(ActionEvent e) {
082: heapWalker.setEnabled(false);
083: walkHeapOffEDT();
084: }
085: });
086: buttons.add(heapWalker);
087: JButton dfilter = new JButton(new DefaultFilter(fc));
088: buttons.add(dfilter);
089: JButton cfilter = new JButton("Clear filter");
090: cfilter.addActionListener(new ActionListener() {
091: public void actionPerformed(ActionEvent e) {
092: fc.setFilter(new AcceptAllFilter());
093: }
094: });
095: buttons.add(cfilter);
096: MemoryMXBean mbean = ph.getMemoryMXBean();
097: JButton memory = new JButton(new MemoryInfo(ph));
098: buttons.add(memory);
099:
100: statusLabel = new JLabel("Starting up");
101: statusLabel.setBorder(BorderFactory.createLoweredBevelBorder());
102:
103: frame.add(buttons, BorderLayout.NORTH);
104: MemoryGraph mg = new MemoryGraph(mbean);
105: mg.start();
106: frame.add(mg, BorderLayout.CENTER);
107: frame.add(statusLabel, BorderLayout.SOUTH);
108: frame.setDefaultCloseOperation(JFrame.DO_NOTHING_ON_CLOSE);
109: frame.pack();
110: frame.setVisible(true);
111: }
112:
113: public void showHeapWalkResult(final List<HeapWalkEntry> ls) {
114: long heapWalkEnded = System.currentTimeMillis();
115: long diff = heapWalkStarted - heapWalkEnded;
116: showStatus(String.format("heap walking took %d millis", diff));
117: if (EventQueue.isDispatchThread()) {
118: showHeapWalkTable(ls);
119: } else {
120: EventQueue.invokeLater(new Runnable() {
121: public void run() {
122: showHeapWalkTable(ls);
123: }
124: });
125: }
126: }
127:
128: private void showHeapWalkTable(List<HeapWalkEntry> ls) {
129: heapWalker.setEnabled(true);
130: HeapWalkTable tableComponent = new HeapWalkTable(ls, ph, fc);
131: tableComponent.showFrame();
132: }
133:
134: public void gcFinished() {
135: EventQueue.invokeLater(new Runnable() {
136: public void run() {
137: gc.setEnabled(true);
138: }
139: });
140: }
141:
142: private void showInstances(final Class<?> clz,
143: final Object[] objects, final long[] sizes,
144: final int[] lengths) {
145: InstanceTable it = new InstanceTable(ph, clz, objects, sizes,
146: lengths);
147: it.showFrame();
148: }
149:
150: public void instances(final Class<?> clz, final Object[] objects,
151: final long[] sizes, final int[] lengths) {
152: if (EventQueue.isDispatchThread()) {
153: showInstances(clz, objects, sizes, lengths);
154: } else {
155: EventQueue.invokeLater(new Runnable() {
156: public void run() {
157: showInstances(clz, objects, sizes, lengths);
158: }
159: });
160: }
161: }
162:
163: private void showStrings(final Object[] objects) {
164: StringTree st = new StringTree(objects);
165: showFrame("Strings", st);
166: }
167:
168: public void strings(final Object[] objects) {
169: if (EventQueue.isDispatchThread()) {
170: showStrings(objects);
171: } else {
172: EventQueue.invokeLater(new Runnable() {
173: public void run() {
174: showStrings(objects);
175: }
176: });
177: }
178: }
179:
180: private void showChildObjects(Object[] objects) {
181: ChildObjectTable ct = new ChildObjectTable(objects);
182: showFrame("Child objects summary", ct);
183: }
184:
185: public void childObjects(final Object[] objects) {
186: if (EventQueue.isDispatchThread()) {
187: showChildObjects(objects);
188: } else {
189: EventQueue.invokeLater(new Runnable() {
190: public void run() {
191: showChildObjects(objects);
192: }
193: });
194: }
195: }
196:
197: private void showFrame(String title, JComponent comp) {
198: new ShowSimpleFrame().showFrame(title, comp);
199: }
200:
201: public void owners(final Map<Long, OwnerInfoHeader> owners,
202: final long[] startObjects) {
203: if (EventQueue.isDispatchThread()) {
204: OwnerInfoTree oit = new OwnerInfoTree(ph, owners,
205: startObjects);
206: showFrame("Object owner information", oit);
207: } else {
208: EventQueue.invokeLater(new Runnable() {
209: public void run() {
210: OwnerInfoTree oit = new OwnerInfoTree(ph, owners,
211: startObjects);
212: showFrame("Object owner information", oit);
213: }
214: });
215: }
216: }
217:
218: public void showStatus(final String status) {
219: if (EventQueue.isDispatchThread()) {
220: statusLabel.setText(status);
221: } else {
222: EventQueue.invokeLater(new Runnable() {
223: public void run() {
224: statusLabel.setText(status);
225: }
226: });
227: }
228: }
229: }
|