Merge "Move preloaded-classes out of framework.jar." into lmp-mr1-dev

This commit is contained in:
Ying Wang
2014-11-17 18:14:04 +00:00
committed by Android (Google) Code Review
2 changed files with 80 additions and 79 deletions

View File

@@ -402,9 +402,6 @@ LOCAL_DX_FLAGS := --core-library --multi-dex
LOCAL_RMTYPEDEFS := true LOCAL_RMTYPEDEFS := true
# List of classes and interfaces which should be loaded by the Zygote.
LOCAL_JAVA_RESOURCE_FILES += $(LOCAL_PATH)/preloaded-classes
include $(BUILD_JAVA_LIBRARY) include $(BUILD_JAVA_LIBRARY)
framework_module := $(LOCAL_INSTALLED_MODULE) framework_module := $(LOCAL_INSTALLED_MODULE)

View File

@@ -45,6 +45,8 @@ import libcore.io.IoUtils;
import java.io.BufferedReader; import java.io.BufferedReader;
import java.io.FileDescriptor; import java.io.FileDescriptor;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException; import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.InputStreamReader; import java.io.InputStreamReader;
@@ -97,9 +99,9 @@ public class ZygoteInit {
static final int GC_LOOP_COUNT = 10; static final int GC_LOOP_COUNT = 10;
/** /**
* The name of a resource file that contains classes to preload. * The path of a file that contains classes to preload.
*/ */
private static final String PRELOADED_CLASSES = "preloaded-classes"; private static final String PRELOADED_CLASSES = "/system/etc/preloaded-classes";
/** Controls whether we should preload resources during zygote init. */ /** Controls whether we should preload resources during zygote init. */
private static final boolean PRELOAD_RESOURCES = true; private static final boolean PRELOAD_RESOURCES = true;
@@ -284,90 +286,92 @@ public class ZygoteInit {
private static void preloadClasses() { private static void preloadClasses() {
final VMRuntime runtime = VMRuntime.getRuntime(); final VMRuntime runtime = VMRuntime.getRuntime();
InputStream is = ClassLoader.getSystemClassLoader().getResourceAsStream( InputStream is;
PRELOADED_CLASSES); try {
if (is == null) { is = new FileInputStream(PRELOADED_CLASSES);
} catch (FileNotFoundException e) {
Log.e(TAG, "Couldn't find " + PRELOADED_CLASSES + "."); Log.e(TAG, "Couldn't find " + PRELOADED_CLASSES + ".");
} else { return;
Log.i(TAG, "Preloading classes..."); }
long startTime = SystemClock.uptimeMillis();
// Drop root perms while running static initializers. Log.i(TAG, "Preloading classes...");
setEffectiveGroup(UNPRIVILEGED_GID); long startTime = SystemClock.uptimeMillis();
setEffectiveUser(UNPRIVILEGED_UID);
// Alter the target heap utilization. With explicit GCs this // Drop root perms while running static initializers.
// is not likely to have any effect. setEffectiveGroup(UNPRIVILEGED_GID);
float defaultUtilization = runtime.getTargetHeapUtilization(); setEffectiveUser(UNPRIVILEGED_UID);
runtime.setTargetHeapUtilization(0.8f);
// Start with a clean slate. // Alter the target heap utilization. With explicit GCs this
System.gc(); // is not likely to have any effect.
runtime.runFinalizationSync(); float defaultUtilization = runtime.getTargetHeapUtilization();
Debug.startAllocCounting(); runtime.setTargetHeapUtilization(0.8f);
try { // Start with a clean slate.
BufferedReader br System.gc();
= new BufferedReader(new InputStreamReader(is), 256); runtime.runFinalizationSync();
Debug.startAllocCounting();
int count = 0; try {
String line; BufferedReader br
while ((line = br.readLine()) != null) { = new BufferedReader(new InputStreamReader(is), 256);
// Skip comments and blank lines.
line = line.trim();
if (line.startsWith("#") || line.equals("")) {
continue;
}
try { int count = 0;
if (false) { String line;
Log.v(TAG, "Preloading " + line + "..."); while ((line = br.readLine()) != null) {
} // Skip comments and blank lines.
Class.forName(line); line = line.trim();
if (Debug.getGlobalAllocSize() > PRELOAD_GC_THRESHOLD) { if (line.startsWith("#") || line.equals("")) {
if (false) { continue;
Log.v(TAG,
" GC at " + Debug.getGlobalAllocSize());
}
System.gc();
runtime.runFinalizationSync();
Debug.resetGlobalAllocSize();
}
count++;
} catch (ClassNotFoundException e) {
Log.w(TAG, "Class not found for preloading: " + line);
} catch (UnsatisfiedLinkError e) {
Log.w(TAG, "Problem preloading " + line + ": " + e);
} catch (Throwable t) {
Log.e(TAG, "Error preloading " + line + ".", t);
if (t instanceof Error) {
throw (Error) t;
}
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
}
throw new RuntimeException(t);
}
} }
Log.i(TAG, "...preloaded " + count + " classes in " try {
+ (SystemClock.uptimeMillis()-startTime) + "ms."); if (false) {
} catch (IOException e) { Log.v(TAG, "Preloading " + line + "...");
Log.e(TAG, "Error reading " + PRELOADED_CLASSES + ".", e); }
} finally { Class.forName(line);
IoUtils.closeQuietly(is); if (Debug.getGlobalAllocSize() > PRELOAD_GC_THRESHOLD) {
// Restore default. if (false) {
runtime.setTargetHeapUtilization(defaultUtilization); Log.v(TAG,
" GC at " + Debug.getGlobalAllocSize());
// Fill in dex caches with classes, fields, and methods brought in by preloading. }
runtime.preloadDexCaches(); System.gc();
runtime.runFinalizationSync();
Debug.stopAllocCounting(); Debug.resetGlobalAllocSize();
}
// Bring back root. We'll need it later. count++;
setEffectiveUser(ROOT_UID); } catch (ClassNotFoundException e) {
setEffectiveGroup(ROOT_GID); Log.w(TAG, "Class not found for preloading: " + line);
} catch (UnsatisfiedLinkError e) {
Log.w(TAG, "Problem preloading " + line + ": " + e);
} catch (Throwable t) {
Log.e(TAG, "Error preloading " + line + ".", t);
if (t instanceof Error) {
throw (Error) t;
}
if (t instanceof RuntimeException) {
throw (RuntimeException) t;
}
throw new RuntimeException(t);
}
} }
Log.i(TAG, "...preloaded " + count + " classes in "
+ (SystemClock.uptimeMillis()-startTime) + "ms.");
} catch (IOException e) {
Log.e(TAG, "Error reading " + PRELOADED_CLASSES + ".", e);
} finally {
IoUtils.closeQuietly(is);
// Restore default.
runtime.setTargetHeapUtilization(defaultUtilization);
// Fill in dex caches with classes, fields, and methods brought in by preloading.
runtime.preloadDexCaches();
Debug.stopAllocCounting();
// Bring back root. We'll need it later.
setEffectiveUser(ROOT_UID);
setEffectiveGroup(ROOT_GID);
} }
} }