/* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import java.io.IOException; import java.io.FileReader; import java.io.BufferedReader; import java.io.PrintStream; import java.util.Set; import java.util.TreeSet; import java.util.HashSet; import java.util.Iterator; /** * Prints HTML containing removed and added files. */ public class PrintHtmlDiff { private static final String OLD_PRELOADED_CLASSES = "old-preloaded-classes"; public static void main(String[] args) throws IOException, ClassNotFoundException { Root root = Root.fromFile(args[0]); BufferedReader oldClasses = new BufferedReader( new FileReader(OLD_PRELOADED_CLASSES)); // Classes loaded implicitly by the zygote. Set zygote = new HashSet(); for (Proc proc : root.processes.values()) { if (proc.name.equals("zygote")) { for (Operation op : proc.operations) { zygote.add(op.loadedClass); } break; } } Set removed = new TreeSet(); Set added = new TreeSet(); for (LoadedClass loadedClass : root.loadedClasses.values()) { if (loadedClass.preloaded && !zygote.contains(loadedClass)) { added.add(loadedClass); } } String line; while ((line = oldClasses.readLine()) != null) { line = line.trim(); LoadedClass clazz = root.loadedClasses.get(line); if (clazz != null) { added.remove(clazz); if (!clazz.preloaded) removed.add(clazz); } } PrintStream out = System.out; out.println(""); out.println(""); out.println(""); out.println("

Removed"); out.println("

Added

"); printTable(out, root.baseline, added); out.println("

Removed

"); printTable(out, root.baseline, removed); out.println(""); } static void printTable(PrintStream out, MemoryUsage baseline, Iterable classes) { out.println(""); out.println(""); out.println(""); out.println(""); out.println(""); out.println(""); out.println(""); out.println(""); for (LoadedClass clazz : classes) { out.println(""); out.println(""); out.println(""); out.println(""); if (clazz.memoryUsage.isAvailable()) { MemoryUsage subtracted = clazz.memoryUsage.subtract(baseline); out.println(""); out.println(""); } else { for (int i = 0; i < 2; i++) { out.println(""); } } out.println(""); } out.println("
NameLoad Time (us)Loaded ByHeap (B)Pages
" + clazz.name + "" + clazz.medianTimeMicros() + ""); Set procNames = new TreeSet(); for (Operation op : clazz.loads) procNames.add(op.process.name); for (Operation op : clazz.initializations) { procNames.add(op.process.name); } if (procNames.size() <= 3) { for (String name : procNames) { out.print(name + "
"); } } else { Iterator i = procNames.iterator(); out.print(i.next() + "
"); out.print(i.next() + "
"); out.print("...and " + (procNames.size() - 2) + " others."); } out.println("
" + (subtracted.javaHeapSize() + subtracted.nativeHeapSize) + "" + subtracted.totalPages() + "n/a
"); } }