001: package tijmp;
002:
003: import java.lang.management.ManagementFactory;
004: import java.lang.management.MemoryMXBean;
005: import java.lang.management.MemoryPoolMXBean;
006: import java.util.ArrayList;
007: import java.util.Collections;
008: import java.util.HashMap;
009: import java.util.List;
010: import java.util.Map;
011: import java.util.concurrent.LinkedBlockingQueue;
012: import tijmp.UIHandler;
013: import tijmp.ui.InVMUI;
014:
015: /** This is a class that can be used to control the tijmp profiler from within java code.
016: */
017: public class TIJMPController {
018: private static List<HeapWalkEntry> previousEntries;
019: private static LinkedBlockingQueue<Runnable> lbq;
020: private static UIHandler uiHandler;
021: private static boolean showStrings = false;
022:
023: static {
024: System.loadLibrary("tijmp");
025: }
026:
027: /** This will run the garbage collector.
028: * According to the specification this type of gc will
029: * actually be guaranteed to run the garbage collector.
030: */
031: static native void runGC();
032:
033: /** Walk the heap and gather object information.
034: */
035: static native void walkHeap();
036:
037: /** Find all entries of a given class and then call back into java to
038: * show them.
039: */
040: static native void showInstances(Class<?> clz);
041:
042: /** Finds all strings and then call back to java to show them.
043: */
044: static void showStrings() {
045: showStrings = true;
046: showInstances(char[].class);
047: }
048:
049: /** Find owners for all objects of the given class and show them.
050: */
051: static native void showOwners(Class<?> clz);
052:
053: /** Find all objects below the given object and show a summary.
054: */
055: static native void childObjectsSummary(Object o);
056:
057: /** Find the objects for a set of tags.
058: */
059: static native Object[] getObjectsForTags(long[] tags);
060:
061: public static void init() {
062: lbq = new LinkedBlockingQueue<Runnable>();
063: Thread runner = new Thread(new EventHandler(lbq));
064: runner.start();
065: uiHandler = new InVMUI();
066: uiHandler.init(new InVMPH());
067: }
068:
069: /** Submit a long running task to the tijmp task handler.
070: */
071: static void submitTask(Runnable r) {
072: try {
073: lbq.put(r);
074: } catch (InterruptedException e) {
075: e.printStackTrace();
076: }
077: }
078:
079: public static void heapWalkResult(Class<?>[] carr, long[] counts,
080: long[] sizes) {
081: Map<Class<?>, HeapWalkEntry> m = Collections.emptyMap();
082: if (previousEntries != null) {
083: m = new HashMap<Class<?>, HeapWalkEntry>(previousEntries
084: .size());
085: for (HeapWalkEntry e : previousEntries)
086: m.put(e.getEntryClass(), e);
087: }
088: final List<HeapWalkEntry> ls = new ArrayList<HeapWalkEntry>(
089: carr.length);
090: for (int i = 0; i < carr.length; i++) {
091: // for now we ignore null entries and also no-count entries.
092: if (carr[i] != null && counts[i] > 0) {
093: HeapWalkEntry pe = m.get(carr[i]);
094: long countChange = 0;
095: long sizeChange = 0;
096: if (pe != null) {
097: countChange = counts[i] - pe.getInstanceCount();
098: sizeChange = sizes[i] - pe.getTotalSize();
099: }
100: ls.add(new HeapWalkEntry(carr[i], counts[i],
101: countChange, sizes[i], sizeChange));
102: }
103: }
104: previousEntries = ls;
105: uiHandler.showHeapWalkResult(ls);
106: }
107:
108: public static void instances(Class<?> clz, Object[] objects,
109: long[] sizes, int[] lengths) {
110: if (showStrings)
111: uiHandler.strings(objects);
112: else
113: uiHandler.instances(clz, objects, sizes, lengths);
114: showStrings = false;
115: }
116:
117: public static void childObjects(Object[] childs) {
118: uiHandler.childObjects(childs);
119: }
120:
121: public static void owners(Map<Long, OwnerInfoHeader> owners,
122: long[] startObjects) {
123: uiHandler.owners(owners, startObjects);
124: }
125:
126: public static void setStatus(String status) {
127: uiHandler.showStatus(status);
128: }
129: }
130:
131: class InVMPH implements ProfilerHandler {
132: public void submitTask(Runnable r) {
133: TIJMPController.submitTask(r);
134: }
135:
136: public void runGC() {
137: TIJMPController.runGC();
138: }
139:
140: public void walkHeap() {
141: TIJMPController.walkHeap();
142: }
143:
144: public void childObjectsSummary(Object o) {
145: TIJMPController.childObjectsSummary(o);
146: }
147:
148: public Object[] getObjectsForTags(long[] tags) {
149: return TIJMPController.getObjectsForTags(tags);
150: }
151:
152: public void showInstances(Class<?> clz) {
153: TIJMPController.showInstances(clz);
154: }
155:
156: public void showStrings() {
157: TIJMPController.showStrings();
158: }
159:
160: public void showOwners(Class<?> clz) {
161: TIJMPController.showOwners(clz);
162: }
163:
164: public MemoryMXBean getMemoryMXBean() {
165: return ManagementFactory.getMemoryMXBean();
166: }
167:
168: public List<MemoryPoolMXBean> getMemoryPoolMXBeans() {
169: return ManagementFactory.getMemoryPoolMXBeans();
170: }
171: }
|