FileDocCategorySizeDatePackage
GlobalData.javaAPI DocphoneME MR2 API (J2ME)16108Wed May 02 17:59:48 BST 2007com.sun.cldchi.tools.memoryprofiler.data

GlobalData

public class GlobalData extends Object implements MPDataProvider

Fields Summary
private com.sun.cldchi.tools.memoryprofiler.jdwp.VMConnection
_connector
private int
_heap_start
private int
_heap_top
private int
_old_gen_end
private int
_allocation_top
private HashMap
_allJavaObjects
private HashMap
_allClasses
private static final int
MPGetGlobalData
private static final int
MPGetHeapData
private static final int
MPGetClasses
private static final int
MPGetRoots
private static final int
MPVMSuspend
private static final int
MPVMResume
private static final int
MPVMStackTrace
public static final String
InternalObjectName
public static final String
StaticsObjectName
public static final String
StackObjectName
private static final int
CLASS_ID_OFFSET
private static final int
TASK_ID_OFFSET
private static final int
OBJ_TYPE_OFFSET
Constructors Summary
GlobalData(com.sun.cldchi.tools.memoryprofiler.jdwp.VMConnection connection)

    _connector = connection;
  
Methods Summary
private voidcalculateDeadObjects()

    boolean was_updated = true;
    while (was_updated) {
      was_updated = false;
      for (Iterator it = _allJavaObjects.values().iterator(); it.hasNext(); ) {
        JavaObject elem = (JavaObject)it.next();
        if (elem.getRootDistance() == -1)
          continue;
        Object[] refs = elem.get_references();
        for (int i = 0; i < refs.length; i++) {
          JavaObject obj = (JavaObject)refs[i];
          if (obj.getRootDistance() == -1) {
            obj.setRootDistance(elem.getRootDistance() + 1);
            was_updated = true;
          } else if (obj.getRootDistance() > 1 + elem.getRootDistance()) {
            obj.setRootDistance(elem.getRootDistance() + 1);
            was_updated = true;
          }
        }
      } 
    }   
  
public ClassStatistics[]calculateStatistics()


    ClassStatistics.reset();
    int count = _allClasses.values().size() + 1;
    HashMap result = new HashMap(count);
    for (Iterator it = _allClasses.values().iterator(); it.hasNext();) {
      JavaClass item = (JavaClass)it.next();
      result.put(new Integer(item.id), new ClassStatistics(item.name));
    }
    result.put(new Integer(-1), new ClassStatistics("Internal VM Objects"));
    for (Iterator it = _allJavaObjects.values().iterator(); it.hasNext();) {
      JavaObject obj = (JavaObject)it.next();
      int type_id = obj.class_id;      
      if (obj.object_type != JAVA_OBJECT) {
         type_id = -1;
      }
      ClassStatistics cls = (ClassStatistics)result.get(new Integer(type_id));
      if (cls == null) continue; //shall not happend
      cls.add(obj, get_old_gen_end());
    }
    Object[] arr = result.values().toArray();
    Arrays.sort(arr, new Comparator() {
      public int compare(Object obj1, Object obj2) {
        ClassStatistics cls1 = (ClassStatistics)obj1;
        ClassStatistics cls2 = (ClassStatistics)obj2;
        return cls2.getHeapPercentage() - cls1.getHeapPercentage();
      }  
    });
    ClassStatistics[] res = new ClassStatistics[arr.length];
    for (int i = 0; i < res.length; i++) {
      res[i] = (ClassStatistics)arr[i];
    }

    return res;    
  
public voidcloseConnections()

     reset();
    _connector.closeConnections();
  
public voidconnect(java.lang.String hostName, int port)

    _connector.connect(hostName, port);    
    update();
  
private voidgetAllData()

    int read = 1;
    int oread = 1;
    _allJavaObjects.clear();
    try {
      while (true) {
        VMReply r = _connector.sendReplyCommand(MPGetHeapData);
        int object_address = r.getInt();
        while (object_address != -1 && object_address != -2) {
          int size = r.getInt();
          int mp_class_id = r.getInt();
          int object_type = mp_class_id >> OBJ_TYPE_OFFSET;
          int stack_number = -1;
          if (object_type == STACK_OBJECT) {
            stack_number = r.getInt();
            read++;
          } 
          int links = r.getInt();
          int[] refs = new int[links];
          HashMap offsets = new HashMap(links);
          if (object_type == STACK_OBJECT) {
            for (int i = 0; i < links; i++) {
              refs[i] = r.getInt();
              int offset = r.getInt();
              Integer cur_offset = (Integer)offsets.get(new Integer(refs[i]));
              if (cur_offset == null || cur_offset.intValue() < offset) {
                offsets.put(new Integer(refs[i]), new Integer(offset));
              }
            }
            read += links;
          } else {
            for (int i = 0; i < links; i++) {
              refs[i] = r.getInt();
            }
          }
          mp_class_id = mp_class_id & 0x7FFFFF;
          JavaClass class_item = (JavaClass)_allClasses.get(new Integer(mp_class_id));
          int class_id = mp_class_id;
          if (class_item != null) {
            class_id = class_item.id;
          }
          if (object_type == JAVA_OBJECT) {
            _allJavaObjects.put(new Integer(object_address), 
               new JavaObject(object_address, class_id, size, refs, JAVA_OBJECT));
          } else if (object_type == STATICS_OBJECT) {
            _allJavaObjects.put(new Integer(object_address), 
               new JavaObject(object_address, class_id, size, refs, STATICS_OBJECT));
          } else if (object_type == STACK_OBJECT) {
            _allJavaObjects.put(new Integer(object_address), 
               new JavaObject(object_address, -1, size, refs, STACK_OBJECT, offsets, stack_number));
          } else if (object_type == VM_OBJECT) {
            _allJavaObjects.put(new Integer(object_address), 
               new JavaObject(object_address, -1, size, refs, VM_OBJECT));
          } else {
            System.out.println("Wrong response from VM! Unknown object type. Skipped!");
          }
          object_address = r.getInt();
          read += 4;
          read += links;
          oread++;
        }         
        if (object_address == -1) break;
      }
    } catch (Exception e) {
      reset();
      throw new SocketException(e.getMessage());
    }
    updateAllObjects();
  
public JavaClass[]getClassList()

    _allClasses.clear();
    JavaClass[] result = null;
    try {
      VMReply r = _connector.sendReplyCommand(MPGetClasses);
      int classesCount = r.getInt();
      result = new JavaClass[classesCount];
      for(int i=0 ; i<classesCount ; i++){
        int class_id = (int)r.getInt();
        String class_name = objectTypeNameFromJNI(r.getString());
        JavaClass new_item = new JavaClass(class_id, class_name);
        _allClasses.put(new Integer(class_id), new_item);
        result[i] = new_item;
      }
    } catch (Exception e) {
      reset();
      throw new SocketException(e.getMessage());
    }
    return result;
  
private JavaObjectgetObjectByAddress(int address)

    Integer key = new Integer(address);
    return (JavaObject)_allJavaObjects.get(key);
  
public java.lang.StringgetObjectTypeName(JavaObject obj)

    if (obj.object_type == JAVA_OBJECT || obj.object_type == STATICS_OBJECT) {
      JavaClass item = (JavaClass)_allClasses.get(new Integer(obj.class_id)); 
      if (item == null) { //this is just for debug!
        System.out.println(obj.class_id);
        System.out.println(obj.object_type);
        return "null!";
      }
      if (obj.object_type == JAVA_OBJECT) {
        return item.name;
      } else { //statics object
        return StaticsObjectName + item.name;
      }    
    } else if (obj.object_type == STACK_OBJECT) {
      return StackObjectName;
    } else if (obj.object_type == VM_OBJECT) {        
      return InternalObjectName;
    } else {
      return "Wrong object type! Report a bug please!";
    }
  
public java.util.IteratorgetObjects()

    return _allJavaObjects.values().iterator();
  
public JavaObject[]getObjectsFromTheAddresses(int start, int end)

    if (start > end) throw new RuntimeException();
    int obj_count = 0;
    for (Iterator it = _allJavaObjects.values().iterator(); it.hasNext(); ) {
      JavaObject obj = (JavaObject)it.next();
      if (obj.address + obj.size > start && obj.address < end) {
        obj_count++;
      }
    }
    JavaObject[] result = new JavaObject[obj_count];
    obj_count = 0;
    for (Iterator it = _allJavaObjects.values().iterator(); it.hasNext(); ) {
      JavaObject obj = (JavaObject)it.next();
      if (obj.address + obj.size > start && obj.address < end) {
        result[obj_count++] = obj;
      }
    }
    Arrays.sort(result, new Comparator() {
     public int	compare(Object o1, Object o2) {
       return ((JavaObject)o1).address - ((JavaObject)o2).address;
     } 
    });
    return result;
  
public JavaObject[]getObjectsOfClass(JavaClass jc)

    if (jc == null) return new JavaObject[0];
    int obj_count = 0;
    int class_id = jc.id;

    for (Iterator it = _allJavaObjects.values().iterator(); it.hasNext(); ) {
      JavaObject elem = (JavaObject)it.next();
      if (elem.object_type == JAVA_OBJECT && elem.class_id == class_id)
        obj_count++;
    } 
    JavaObject result[] = new JavaObject[obj_count];
    obj_count = 0;
    for (Iterator it = _allJavaObjects.values().iterator(); it.hasNext(); ) {
      JavaObject elem = (JavaObject)it.next();
      if (elem.object_type == JAVA_OBJECT && elem.class_id == class_id)
        result[obj_count++] = elem;
    }
    return result;
  
private voidgetRoots()

    try {
      VMReply r = _connector.sendReplyCommand(MPGetRoots);
      int root = r.getInt();
      while (root != -1) {
        Integer key = new Integer(root);
        JavaObject obj = (JavaObject)_allJavaObjects.get(key);
        if (obj != null) {
          obj.setRootDistance(0);
        }
        root = r.getInt();
      }
    } catch (Exception e) {
      reset();
      throw new SocketException(e.getMessage());
    }

  
public java.lang.StringgetStackTrace(JavaObject stack_object, int ptr)

    if (stack_object.object_type != STACK_OBJECT) {
      return "JavaObject of wrong type type was passed to MPDataProvider.getStackTrace.\n" +
                   "Please report a bug!";
    }
    int[] params = new int[2];    
    params[0] = stack_object._stack_id;
    Integer offset = (Integer)stack_object._stack_offsets.get(new Integer(ptr));
    params[1] = offset.intValue();
    String result = null;
    try {
      VMReply reply = _connector.sendReplyCommand(MPVMStackTrace, params);
      result = reply.getString();
    } catch (Exception e) {
      result = "VM connection is broken!";
      reset();
      throw new SocketException(e.getMessage());
    }
    return result;
  
public intget_allocation_top()

return _allocation_top;
public intget_heap_start()


     return _heap_start;
public intget_heap_top()

return _heap_top;
public intget_old_gen_end()

return _old_gen_end;
private java.lang.StringobjectTypeNameFromJNI(java.lang.String jniTypeName)
Converts object type name from JNI form to javap-like form (for example, Ljava/lang/String; will be converted to java.lang.String). This method is used by fields and methods KJDB commands.

param
jniTypeName an object type name in JNI form
return
an object type name in javap-like form

    if(jniTypeName.indexOf("L") != 0 ||
      jniTypeName.lastIndexOf(";") != jniTypeName.length() - 1){
        return jniTypeName;
    }
    char[] chars = new char[jniTypeName.length()-2];
    jniTypeName.getChars(1,jniTypeName.length()-1,chars,0);
    for(int i=0 ; i<chars.length ; i++){
      if(chars[i] == '/"){
        chars[i] = '.";
      }
    }
    return new String(chars);
  
public JavaObject[]pathFromTheRoot(JavaObject obj)

    if (obj == null) return null;
    if (obj.getRootDistance() == -1) return null;
    JavaObject[] result = new JavaObject[obj.getRootDistance() + 1];
    int dst = obj.getRootDistance();
    while (dst > 0) { 
      result[dst--] = obj;
      Object[] referees = obj.get_referees();
      for (int i = 0; i < referees.length; i++) {
        JavaObject elem = (JavaObject)referees[i];
        if (elem.getRootDistance() == obj.getRootDistance() - 1) {
          obj = elem; break;
        }
      }      
      if (dst != obj.getRootDistance()) throw new RuntimeException("problem here!");      
    }
    result[dst--] = obj;
    return result;
  
public voidpauseVM()

 
    try {
      _connector.sendCommand(MPVMSuspend);
      update();
    } catch (Exception e ) {
      reset();
      throw new SocketException(e.getMessage());
    }
  
private voidreset()

    _heap_start = 0;
    _heap_top = 0;
    _old_gen_end = 0;
    _allocation_top = 0;
    _allJavaObjects.clear();
    _allClasses.clear();
    ClassStatistics.reset();
  
public voidresumeVM()

 
    try {
      reset();
      _connector.sendCommand(MPVMResume);
    } catch (Exception e ) {
      reset();
      throw new SocketException(e.getMessage());
    }
  
private voidsetConnector(com.sun.cldchi.tools.memoryprofiler.jdwp.VMConnection connector)

    if (_connector == null ) {
      _connector = connector;
      return;
    }
    if (_connector.isConnected()) {
      throw new IllegalStateException("Another connector is connected to the VM");
    }
    _connector = connector;
    reset();
  
private voidupdate()

    getClassList();
    getAllData();
    getRoots();
    try {
      VMReply r = _connector.sendReplyCommand(MPGetGlobalData);
      _heap_start =     r.getInt();
      _heap_top =       r.getInt();
      _old_gen_end =    r.getInt();
      _allocation_top = r.getInt();
    }catch(DebugeeException e) {
      reset();
      throw new SocketException(e.getMessage());
    }catch(BoundException e) {
      reset();
      throw new SocketException(e.getMessage());
    }
    calculateDeadObjects();
  
private voidupdateAllObjects()

    for (Iterator it = _allJavaObjects.values().iterator(); it.hasNext();) {
      JavaObject obj = (JavaObject)it.next();
      for (int i = 0; i < obj._references_addresses.length; i++) {
        JavaObject ref = getObjectByAddress(obj._references_addresses[i]);
        if (ref != null) {
          obj.add_reference(ref);
          ref.add_referee(obj);
        } 
      }
    }