FileDocCategorySizeDatePackage
ObjectCreationMonitoring.javaAPI DocExample4920Tue Jan 11 16:01:10 GMT 2000tuning.profile

ObjectCreationMonitoring.java

package tuning.profile;
import java.util.*;
import java.io.*;
import java.lang.reflect.*;

public class ObjectCreationMonitoring
{
  private static int MonitoringMode = 0;
  private static int StackModeCount = -1;
  public static final int VERBOSE_MODE = 1;
  public static final int TALLY_MODE = 2;
  public static final int GET_STACK_MODE = 3;

  public static void main(String args[])
  {
    try
    {
      //First argument is the option specifying which type of monitoring
      if(args[0].startsWith("-v"))
        //verbose creation - just prints every object's class as its created
        MonitoringMode = VERBOSE_MODE;
      else if(args[0].startsWith("-t"))
        //tally mode. Tally classes and print results at end
        MonitoringMode = TALLY_MODE;
      else if(args[0].startsWith("-s"))
      {
        //stack mode. Print stacks of objects as they are created
        MonitoringMode = GET_STACK_MODE;
        if(args[0].length() > 2)
          StackModeCount = Integer.parseInt(args[0].substring(2));
      }
      else
        throw new IllegalArgumentException("First command line argument must be one of -v/-t/-s");

      //Remaining arguments are the class with the main() method, and its arguments
      String classname = args[1];
      String[] argz = new String[args.length-2];
      System.arraycopy(args, 2, argz, 0, argz.length);
      Class clazz = Class.forName(classname);

      //main has one parameter, a String array.
      Class[] mainParamType = {args.getClass()}; 
      Method main = clazz.getMethod("main", mainParamType);
      Object[] mainParams = {argz};

      //start monitoring
      ObjectCreationMonitoringFlag.monitoring = true;
      main.invoke(null, mainParams);
      //stop monitoring
      ObjectCreationMonitoringFlag.monitoring = false;
      if (MonitoringMode == TALLY_MODE)
        printTally();
      else if (MonitoringMode == GET_STACK_MODE)
        printStacks();
    }
    catch(Exception e)
    {
      e.printStackTrace();
    }
  }

  public static void monitor(Object o)
  {
    //Disable object creation monitoring while we report
    ObjectCreationMonitoringFlag.monitoring = false;

    switch(MonitoringMode)
    {
      case 1: justPrint(o); break;
      case 2: tally(o); break;
      case 3: getStack(o); break;
      default: System.out.println("Undefined mode for ObjectCreationMonitoring class"); break;
    }

    //Re-enable object creation monitoring
    ObjectCreationMonitoringFlag.monitoring = true;
  }

  public static void justPrint(Object o)
  {
    System.out.println(o.getClass().getName());
  }

  private static Hashtable Hash = new Hashtable();
  public static void tally(Object o)
  {
    //You need to print the tally from printTally()
    //at the end of the application
    Integer i = (Integer) Hash.get(o.getClass());
    if (i == null)
      i = new Integer(1);
    else
      i = new Integer(i.intValue() + 1);
    Hash.put(o.getClass(), i);
  }
  public static void printTally()
  {
    //should really sort the elements in order of the
    //number of objects created, butI will just print them
    //out inany order here.
    Enumeration e = Hash.keys();
    Class c;
    String s;
    while(e.hasMoreElements())
    {
      c = (Class) e.nextElement();
      System.out.print(s = c.getName());
      for (int i = 31-s.length(); i >= 0; i--)
        System.out.print(' ');
      System.out.print("\t");
      System.out.println(Hash.get(c));
    }
  }

  private static Exception Ex = new Exception();
  private static ByteArrayOutputStream MyByteStream = new ByteArrayOutputStream();
  private static PrintStream MyPrintStream = new PrintStream(MyByteStream);
  public static void getStack(Object o)
  {
    if (StackModeCount > 0)
	StackModeCount--;
    else if (StackModeCount != -1)
        return;
    Ex.fillInStackTrace();
    MyPrintStream.flush();
    MyByteStream.reset();
    MyPrintStream.print("Creating object of type ");
    MyPrintStream.println(o.getClass().getName());
    //Note that the first two lines of the stack will be getStack() and monitor()
    //and these can be ignored.
    Ex.printStackTrace(MyPrintStream);
    MyPrintStream.flush();
    String trace = new String(MyByteStream.toByteArray());
    Integer i = (Integer) Hash.get(trace);
    if (i == null)
      i = new Integer(1);
    else
      i = new Integer(i.intValue() + 1);
    Hash.put(trace, i);
  }

  public static void printStacks()
  {
    Enumeration e = Hash.keys();
    String s;
    while(e.hasMoreElements())
    {
      s = (String) e.nextElement();
      System.out.print("Following stack contructed ");
      System.out.print(Hash.get(s));
      System.out.println(" times:");
      System.out.println(s);
      System.out.println();
    }
  }

}