diff options
author | Bob Lee <crazybob@google.com> | 2009-08-13 14:41:54 -0700 |
---|---|---|
committer | Bob Lee <crazybob@google.com> | 2009-08-17 15:36:15 -0700 |
commit | 9d2d6e14b0932b6a74e01f393d5efed61458941b (patch) | |
tree | 833ec805d5f8eded7819bd98fea6587ed2098501 /tools/preload/WritePreloadedClassFile.java | |
parent | 802527c6a8a91f7da72f2ce9f6cb3cc342582127 (diff) |
Simplified algorithm used to generate the preloaded-classes list. Generated a new preloaded-classes file.
Diffstat (limited to 'tools/preload/WritePreloadedClassFile.java')
-rw-r--r-- | tools/preload/WritePreloadedClassFile.java | 98 |
1 files changed, 64 insertions, 34 deletions
diff --git a/tools/preload/WritePreloadedClassFile.java b/tools/preload/WritePreloadedClassFile.java index b209af0c25f6..96c539bb727e 100644 --- a/tools/preload/WritePreloadedClassFile.java +++ b/tools/preload/WritePreloadedClassFile.java @@ -24,12 +24,18 @@ import java.util.Set; import java.util.TreeSet; /** - * Writes /frameworks/base/preloaded-classes. Also updates LoadedClass.preloaded - * fields and writes over compiled log file. + * Writes /frameworks/base/preloaded-classes. Also updates + * {@link LoadedClass#preloaded} fields and writes over compiled log file. */ public class WritePreloadedClassFile { - public static void main(String[] args) throws IOException, ClassNotFoundException { + /** + * Preload any class that take longer to load than MIN_LOAD_TIME_MICROS us. + */ + static final int MIN_LOAD_TIME_MICROS = 1250; + + public static void main(String[] args) throws IOException, + ClassNotFoundException { if (args.length != 1) { System.err.println("Usage: WritePreloadedClassFile [compiled log]"); System.exit(-1); @@ -44,48 +50,64 @@ public class WritePreloadedClassFile { // Open preloaded-classes file for output. Writer out = new BufferedWriter(new OutputStreamWriter( - new FileOutputStream(Policy.getPreloadedClassFileName()), + new FileOutputStream(Policy.PRELOADED_CLASS_FILE), Charset.forName("US-ASCII"))); - out.write("# Classes which are preloaded by com.android.internal.os.ZygoteInit.\n"); - out.write("# Automatically generated by /frameworks/base/tools/preload.\n"); - out.write("# percent=" + Proc.PERCENTAGE_TO_PRELOAD - + ", weight=" + ClassRank.SEQUENCE_WEIGHT - + ", bucket_size=" + ClassRank.BUCKET_SIZE - + "\n"); - + out.write("# Classes which are preloaded by" + + " com.android.internal.os.ZygoteInit.\n"); + out.write("# Automatically generated by frameworks/base/tools/preload/" + + WritePreloadedClassFile.class.getSimpleName() + ".java.\n"); + out.write("# MIN_LOAD_TIME_MICROS=" + MIN_LOAD_TIME_MICROS + "\n"); + + /* + * The set of classes to preload. We preload a class if: + * + * a) it's loaded in the bootclasspath (i.e., is a system class) + * b) it takes > MIN_LOAD_TIME_MICROS us to load, and + * c) it's loaded by more than one process, or it's loaded by an + * application (i.e., not a long running service) + */ Set<LoadedClass> toPreload = new TreeSet<LoadedClass>(); - // Preload all classes that were loaded by at least 2 apps, if both - // apps run at the same time, they'll share memory. + // Preload classes that were loaded by at least 2 processes. Hopefully, + // the memory associated with these classes will be shared. for (LoadedClass loadedClass : root.loadedClasses.values()) { - if (!loadedClass.isPreloadable()) { - continue; - } - - Set<String> appNames = loadedClass.applicationNames(); - - if (appNames.size() > 3) { + Set<String> names = loadedClass.processNames(); + if (shouldPreload(loadedClass) && names.size() > 1) { toPreload.add(loadedClass); } } - // Try to make individual apps start faster by preloading slowest - // classes. + int initialSize = toPreload.size(); + System.out.println(initialSize + + " classses were loaded by more than one app."); + + // Preload eligable classes from applications (not long-running + // services). for (Proc proc : root.processes.values()) { - toPreload.addAll(proc.highestRankedClasses()); + if (proc.fromZygote() && !Policy.isService(proc.name)) { + for (Operation operation : proc.operations) { + LoadedClass loadedClass = operation.loadedClass; + if (shouldPreload(loadedClass)) { + toPreload.add(loadedClass); + } + } + } } - System.out.println(toPreload.size() + " classes will be preloaded."); + System.out.println("Added " + (toPreload.size() - initialSize) + + " more to speed up applications."); - // Make classes that were already loaded by the zygote explicit. + System.out.println(toPreload.size() + + " total classes will be preloaded."); + + // Make classes that were implicitly loaded by the zygote explicit. // This adds minimal overhead but avoid confusion about classes not // appearing in the list. - addAllClassesFor("zygote", root, toPreload); + addAllClassesFrom("zygote", root, toPreload); for (LoadedClass loadedClass : toPreload) { - out.write(loadedClass.name); - out.write('\n'); + out.write(loadedClass.name + "\n"); } out.close(); @@ -97,18 +119,26 @@ public class WritePreloadedClassFile { root.toFile(rootFile); } - private static void addAllClassesFor(String packageName, Root root, - Set<LoadedClass> toPreload) { + private static void addAllClassesFrom(String processName, Root root, + Set<LoadedClass> toPreload) { for (Proc proc : root.processes.values()) { - if (proc.name.equals(packageName)) { + if (proc.name.equals(processName)) { for (Operation operation : proc.operations) { - // TODO: I'm not sure how the zygote loaded classes that - // aren't supposed to be preloadable... - if (operation.loadedClass.isPreloadable()) { + boolean preloadable + = Policy.isPreloadable(operation.loadedClass); + if (preloadable) { toPreload.add(operation.loadedClass); } } } } } + + /** + * Returns true if the class should be preloaded. + */ + private static boolean shouldPreload(LoadedClass clazz) { + return Policy.isPreloadable(clazz) + && clazz.medianTimeMicros() > MIN_LOAD_TIME_MICROS; + } } |