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>"); }
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); } } } }