示例#1
0
    public final Object getColumnValue(Object row, int columnIndex) {
      try {
        Node node = (Node) row;

        switch (columnIndex) {
          case 0:
            if (node.label == null) {
              IObject obj = snapshot.getObject(node.objectId);
              node.label = obj.getDisplayName();
              node.shallowHeap = obj.getUsedHeapSize();
            }
            return node.label;
          case 1:
            if (node.shallowHeap == -1) node.shallowHeap = snapshot.getHeapSize(node.objectId);
            return node.shallowHeap;
          case 2:
            if (node.retainedHeap == -1)
              node.retainedHeap = snapshot.getRetainedHeapSize(node.objectId);
            return node.retainedHeap;
        }
      } catch (SnapshotException e) {
        throw new RuntimeException(e);
      }

      return null;
    }
示例#2
0
 private boolean firstObjectDominatesSecond(int clId, int obj, ISnapshot snapshot)
     throws SnapshotException {
   boolean clDominates = false;
   int dom = snapshot.getImmediateDominatorId(obj);
   while (dom != -1 && !clDominates) {
     if (dom == clId) {
       clDominates = true;
     }
     dom = snapshot.getImmediateDominatorId(dom);
   }
   return clDominates;
 }
示例#3
0
 private void outputGeneralObjectInfo(IObject object, String identation) throws SnapshotException {
   String clazzName = object.getClazz().getName();
   String gcRootInfo = "";
   if (snapshot.isGCRoot(object.getObjectId())) {
     gcRootInfo =
         GCRootInfo.getTypeSetAsString(snapshot.getGCRootInfo(object.getObjectId())) + " ";
   }
   if (snapshot.isClass(object.getObjectId())) {
     clazzName = "[Class] " + ((IClass) object).getName();
   }
   String objAddr = Long.toString(object.getObjectAddress(), 16);
   out.println(
       String.format(
           "%s<class><![CDATA[%s @ 0x%s]]></class>", identation, gcRootInfo + clazzName, objAddr));
   out.println(String.format("%s<id>0x%s</id>", identation.toString(), objAddr));
 }
示例#4
0
  public IResult execute(IProgressListener listener) throws Exception {
    int[] retainedSet;

    if (fieldNames == null)
      retainedSet = snapshot.getRetainedSet(objects.getIds(listener), listener);
    else retainedSet = snapshot.getRetainedSet(objects.getIds(listener), fieldNames, listener);

    if (listener.isCanceled()) throw new IProgressListener.OperationCanceledException();

    Histogram histogram = snapshot.getHistogram(retainedSet, listener);

    if (listener.isCanceled()) throw new IProgressListener.OperationCanceledException();

    histogram.setLabel(
        MessageUtil.format(Messages.RetainedSetQuery_RetainedBy, objects.getLabel()));
    return histogram;
  }
 /**
  * Get the only object field from the object Used for finding the HashMap from the HashSet
  *
  * @param source
  * @return null if non or duplicates found
  * @throws SnapshotException
  */
 private IInstance resolveNextField(IObject source) throws SnapshotException {
   final ISnapshot snapshot = source.getSnapshot();
   IInstance ret = null;
   for (int i : snapshot.getOutboundReferentIds(source.getObjectId())) {
     if (!snapshot.isArray(i) && !snapshot.isClass(i)) {
       IObject o = snapshot.getObject(i);
       if (o instanceof IInstance) {
         if (ret != null) {
           ret = null;
           break;
         }
         ret = (IInstance) o;
       }
     }
   }
   return ret;
 }
示例#6
0
  private void write(DataOutputStream out) throws IOException, SnapshotException {
    Stack<Integer> stack = new Stack<Integer>();
    stack.add(-1);
    while (!stack.isEmpty()) {
      int objectId = stack.pop();

      int[] objectIds = snapshot.getImmediateDominatedIds(objectId);
      long[] addresses = new long[objectIds.length];
      for (int i = 0; i < objectIds.length; i++)
        addresses[i] = snapshot.mapIdToAddress(objectIds[i]);

      ArrayUtils.sortDesc(addresses, objectIds);
      for (int i = 0; i < addresses.length; i++) out.writeLong(addresses[i]);

      addresses = null;

      for (int i = objectIds.length - 1; i >= 0; i--) stack.add(objectIds[i]);
    }
  }
示例#7
0
  public ClassloaderLeakDetector(File f) throws Exception {
    IProgressListener listener = new ConsoleProgressListener(System.out);

    SnapshotFactory sf = new SnapshotFactory();
    snapshot = sf.openSnapshot(f, new HashMap<String, String>(), listener);
    int[] retainedSet = snapshot.getRetainedSet(snapshot.getGCRoots(), listener);

    for (int obj : retainedSet) {
      if (snapshot.isClass(obj)) continue;
      int clId = snapshot.getClassOf(obj).getClassLoaderId();
      if (snapshot.getObject(clId).getClazz().getName().startsWith("sun.")) {
        continue;
      }
      Boolean dominatedAllSoFar = clDominationFlags.get(clId);
      if (dominatedAllSoFar != null && !dominatedAllSoFar) continue;

      boolean clDominates = firstObjectDominatesSecond(clId, obj, snapshot);

      if (!clDominates) {
        boolean objDominates = firstObjectDominatesSecond(obj, clId, snapshot);
        if (objDominates) {
          //					System.out.println(String.format(
          //							"Classloader %s IS NOT dominating: %s, but viceversa is true!", snapshot
          //							.getObject(clId).getTechnicalName(), snapshot
          //							.getObject(obj).getTechnicalName()));
          //					printPathToGCRoot(snapshot, obj, false);
          clDominates = true;
        }
      }

      if (dominatedAllSoFar == null) {
        clDominationFlags.put(clId, clDominates);
      } else {
        // If classloader is not dominating the object and
        // it has been dominating everything it loaded so far
        // Then this classloader is no longer dominating.
        if (!clDominates && dominatedAllSoFar) {
          clDominationFlags.put(clId, Boolean.FALSE);
        }
      }
    }
  }
示例#8
0
  private void printPathToGCRoot(ISnapshot snapshot, int obj, boolean printAllPaths)
      throws SnapshotException {

    int dom = snapshot.getImmediateDominatorId(obj);
    ArrayInt path = new ArrayInt();
    path.add(obj);
    while (dom != -1) {
      path.add(dom);
      dom = snapshot.getImmediateDominatorId(dom);
    }
    out.println("<dominator-path>");
    printObjectFromPath(path.toArray());
    out.println("</dominator-path>");

    IPathsFromGCRootsComputer pathsFromGCRoots = snapshot.getPathsFromGCRoots(obj, null);
    List<int[]> paths = new ArrayList<int[]>();

    int[] nextShortestPath = pathsFromGCRoots.getNextShortestPath();
    int pathCount = 0;
    int objectCount = 0;
    while (nextShortestPath != null) {
      pathCount++;
      objectCount += nextShortestPath.length;

      if (pathCount > 500) break;

      //			out.println("<path>");
      //			printObjectFromPath(nextShortestPath);
      //			out.println("</path>");
      if (!printAllPaths) break;
      paths.add(nextShortestPath);
      nextShortestPath = pathsFromGCRoots.getNextShortestPath();
    }
    //		System.out.println(pathCount + " Paths found for Leak");
    //		System.out.println(objectCount + " objects in paths");

    PathsFromGCRootsTree tree = pathsFromGCRoots.getTree(paths);
    out.println("<tree>");
    System.out.println(outputTree(tree, null, "  ") + " objects in path tree");
    out.println("</tree>");
  }
示例#9
0
  public synchronized void dispose(ISnapshot snapshot) {

    for (Iterator<SnapshotEntry> iter = snapshotCache.values().iterator(); iter.hasNext(); ) {
      SnapshotEntry entry = iter.next();

      ISnapshot s = entry.snapshot.get();
      if (s == null) {
        iter.remove();
      } else if (s == snapshot) {
        entry.usageCount--;
        if (entry.usageCount == 0) {
          snapshot.dispose();
          iter.remove();
        }
        return;
      }
    }

    // just in case the snapshot is not stored anymore
    if (snapshot != null) snapshot.dispose();
  }
示例#10
0
    public final String suffix(Object row) {
      Node node = (Node) row;
      if (node.gcRoots == null) {
        try {
          GCRootInfo[] gc = snapshot.getGCRootInfo(node.objectId);
          node.gcRoots = gc != null ? GCRootInfo.getTypeSetAsString(gc) : Node.NOT_A_GC_ROOT;
        } catch (SnapshotException e) {
          throw new RuntimeException(e);
        }
      }

      return node.gcRoots == Node.NOT_A_GC_ROOT ? null : node.gcRoots;
    }
示例#11
0
  private void printObjectFromPath(int[] path) throws SnapshotException {
    StringBuilder closingTags = new StringBuilder();
    for (int index = path.length - 1; index >= 0; index--) {
      IObject object = snapshot.getObject(path[index]);
      String identation = multiplyStr("  ", path.length - index);
      out.println(String.format("%s<object id=\"%d\">", identation, xmlObjectCounter++));

      outputGeneralObjectInfo(object, identation);

      closingTags.insert(0, String.format("%s</object>%n", identation));
      if (index > 0) {
        out.println(identation + "<field>");
        IObject referencingObject = snapshot.getObject(path[index - 1]);
        out.println(
            String.format(
                "%s  <name><![CDATA[%s]]></name>",
                identation, getReferencingFieldName(object, referencingObject)));
        closingTags.insert(0, String.format("%s</field>%n", identation));
      }
    }
    out.print(closingTags);
  }
示例#12
0
 public void outputResultsAsXml(PrintStream where) throws SnapshotException {
   out = where;
   out.println("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
   out.println("<?xml-stylesheet type=\"text/xsl\" href=\"leaks.xsl\"?>");
   out.println("<leaks>");
   for (int loader : clDominationFlags.getAllKeys()) {
     if (clDominationFlags.get(loader)) {
       IObject loaderObj = snapshot.getObject(loader);
       out.println(
           String.format(
               "<leak>%n<classloader>%s</classloader>%n<id>0x%s</id>",
               loaderObj.getClazz().getName(), Long.toString(loaderObj.getObjectAddress(), 16)));
       printPathToGCRoot(snapshot, loader, true);
       out.println("</leak>");
     }
   }
   out.println("</leaks>");
 }
示例#13
0
  public IResult execute(IProgressListener listener) throws Exception {
    FileOutputStream out = null;
    DataOutputStream dout = null;
    try {
      File domTreeBinary = new File(snapshot.getSnapshotInfo().getPrefix() + "Dom_tree.bin");
      out = new FileOutputStream(domTreeBinary);
      dout = new DataOutputStream(out);

      write(dout);
      dout.flush();
      dout.close();

      return new DisplayFileResult(domTreeBinary);
    } finally {
      if (out != null) out.close();
      if (dout != null) dout.close();
    }
  }
  public IResult execute(IProgressListener listener) throws Exception {
    int[] finalizerThreadObjects = FinalizerThreadQuery.getFinalizerThreads(snapshot);

    SetInt result = new SetInt();

    for (int finalizerThreadObject : finalizerThreadObjects) {
      Field localsField =
          ((IInstance) snapshot.getObject(finalizerThreadObject))
              .getField("threadLocals"); // $NON-NLS-1$
      if (localsField != null) {
        ObjectReference ref = (ObjectReference) localsField.getValue();
        if (ref != null) {
          // TODO Don't add the thread locals object, but the pairs of
          // referent and value stored in the thread locals
          result.add(ref.getObjectId());
        }
      }
    }

    return new ObjectListResult.Outbound(snapshot, result.toArray());
  }
示例#15
0
  private int outputTree(PathsFromGCRootsTree tree, IObject objReferencedByRoot, String identation)
      throws SnapshotException {
    out.println(String.format("%s<object id=\"%d\">", identation, xmlObjectCounter++));
    IObject object = snapshot.getObject(tree.getOwnId());

    outputGeneralObjectInfo(object, identation);
    if (objReferencedByRoot != null) {
      out.println(
          String.format(
              "%s    <outbound-ref><![CDATA[%s]]></outbound-ref>",
              identation, getReferencingFieldName(object, objReferencedByRoot)));
    }

    int result = tree.getObjectIds().length;
    out.println(identation + "<incoming-fields>");
    for (int subtree : tree.getObjectIds()) {
      out.println(identation + "  <incoming-field>");
      result += outputTree(tree.getBranch(subtree), object, "    " + identation);
      out.println(identation + "  </incoming-field>");
    }
    out.println(identation + "</incoming-fields>");
    out.println(identation + "</object>");
    return result;
  }
示例#16
0
 /**
  * Get a detailed view of the object
  *
  * @return the object detail
  * @throws SnapshotException
  */
 public IObject getObject() throws SnapshotException {
   return snapshot.getObject(getObjectId());
 }
示例#17
0
 /**
  * The id of the object
  *
  * @return the object id
  * @throws SnapshotException
  */
 public int getObjectId() throws SnapshotException {
   return snapshot.mapAddressToId(address);
 }
  @Override
  public int[] extractEntryIds(IObject list) throws SnapshotException {
    IProgressListener listener = new VoidProgressListener();
    // If there isn't a size, then use an upper limit in case there is a loop
    int size = super.hasSize() ? getSize(list) : 10000000;

    String taskMsg =
        MessageUtil.format(
            Messages.ExtractListValuesQuery_CollectingElements, size, list.getTechnicalName());
    listener.beginTask(taskMsg, size);

    ArrayInt result = new ArrayInt();
    int loopingLimit = size;

    IObject header = (IObject) list.resolveValue("header"); // LinkedList$Header //$NON-NLS-1$
    if (header == null)
      header = (IObject) list.resolveValue("voidLink"); // LinkedList$Link IBM VM //$NON-NLS-1$
    if (header == null)
      header = (IObject) list.resolveValue("first"); // LinkedList$Node Java 7 //$NON-NLS-1$
    if (header == null) {}

    if (header == null) {
      // Look for the only object field
      header = resolveNextFields(list);
    }
    if (header == null) return null;

    IObject previous = header;
    IObject current = header;

    if (current.getClazz().getName().equals("java.util.LinkedList$Entry")
        || //$NON-NLS-1$
        current.getClazz().getName().equals("java.util.LinkedList$Link")
        || //$NON-NLS-1$
        current
            .getClazz()
            .getName()
            .equals("java.util.concurrent.LinkedBlockingQueue$Node")) // $NON-NLS-1$
    {
      // Skip over header link for pre Java 7 implementations
      current = (IObject) header.resolveValue("next"); // $NON-NLS-1$;
      if (current == null) {
        // Try without using field names
        final ISnapshot snapshot = header.getSnapshot();
        for (int i : snapshot.getOutboundReferentIds(header.getObjectId())) {
          IObject o = snapshot.getObject(i);
          // Exclude the class
          if (i != header.getClazz().getObjectId()) {
            if (o.getClazz().equals(header.getClazz())) {
              // same type as header, so possible next field
              // don't care whether we get current or previous -
              // just circle the wrong way
              current = o;
              break;
            }
          }
        }
      }
    } else {
      header = null;
    }

    while (current != null && current != header && loopingLimit-- > 0) {
      // Find the element
      IObject ref = (IObject) current.resolveValue("element"); // $NON-NLS-1$
      if (ref == null) ref = (IObject) current.resolveValue("data"); // IBM VM //$NON-NLS-1$
      if (ref == null) ref = (IObject) current.resolveValue("item"); // Java 7 //$NON-NLS-1$
      if (current.equals(ref)) {
        // java.util.concurrent.LinkedTransferQueue has a spurious link
        ref = null;
      }

      // Find the next link
      IObject next = (IObject) current.resolveValue("next"); // $NON-NLS-1$

      if (next == null) {
        // Try without using field names
        final ISnapshot snapshot = current.getSnapshot();
        for (int i : snapshot.getOutboundReferentIds(current.getObjectId())) {
          IObject o = snapshot.getObject(i);
          // Exclude the previous field and the class
          if (i != previous.getObjectId() && i != current.getClazz().getObjectId()) {
            if (o.getClazz().equals(current.getClazz())) {
              // same type as current, so possible next field
              if (next != null) {
                // Uncertain, so give up
                next = null;
                break;
              }
              next = o;
            } else {
              // possible element
              if (ref == null) ref = o;
            }
          }
        }
      }

      if (ref != null) result.add(ref.getObjectId());
      previous = current;
      current = next;
      listener.worked(1);
      // If the user cancels then just return what we have got so far
      if (listener.isCanceled()) break;
    }

    listener.done();

    return result.toArray();
  }