Androidシステム起動シリーズ---Zygoteプロセス
13407 ワード
引用する
前の文章Androidシステム起動シリーズ---initプロセス、大体分析して、initプロセスの起動過程.最後にZygoteプロセスはapp_プロセスプロセスはJNIによってZygoteInitのmainメソッドを呼び出して開始される.この文章はZygoteプロセスが私たちのために何をしたかを分析します.(システムソース分析はAndroid 6.0.1に基づく)
Zygote機能
まずZygoteInitのmainメソッドを見てみましょう(/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java)注記1:socket通信を登録するサービス側 注記2:プリロード 注記3:SystemServerシステムサービス を開始注記4:socketクライアントの接続要求(新しいアプリケーションappの起動など) をループ待機する.注記5:socketクライアントを実行するリクエスト者のmainメソッド を実行する
SOcket通信のサービス・エンドの登録(registerZygoteSocket)
「zygote」という名前のsocketserverを登録します.
注記1:serversocket静的オブジェクトを作成する
プリロード
SystemServerシステムサービスの起動
a.注釈1:システムサーバを起動するいくつかのパラメータを設定するb.注釈2:パラメータforkに従ってシステム_サーバのプロセス
nativeForkSystemServerメソッドはnativeローカルメソッドの役割であり、forkのSystemServerプロセスである.
c.注釈3:注釈2のpid=0でifの文がSystemServerプロセスで実行することを示すcomを起動する.android.server.SystemServerクラスのmainメソッド.
注記1システムサーバのいくつかのパラメータをRuntimeInitに入力します.zygoteInitメソッド.もう一度見てみろzygoteInitメソッド:注記1:nativeレイヤはいくつか初期化されており、nativeメソッドは/frameworks/base/core/jni/Android Runtimeに対応する.JAvaで. 注記2:java層の初期化アプリケーションInit()
invokeStaticMainメソッドを続行します.
私たちは一緒に降りてclassNameに入るのがcomだと知っています.android.server.SystemServer注記1:Classを反射する.forNameはcomをロードします.android.server.SystemServerのSystemServerclassオブジェクト.注記2:SystemServerを介して.classオブジェクトのSystemServerのmainメソッドを取得するMethodオブジェクト.注釈3:この方法は終わっても実際にinvoke SystemServerのmain方法を反射するのではなくZygoteInitを投げ出した.MethodAndArgsCaller異常はmainメソッドのMethodオブジェクトとパラメータを入力します.明らかにこの異常類が処理したに違いない.じゃあどこを見つけるんだ?catchはこの異常情報を処理した.最終的には最初のZygoteInitで見ることができます.main()メソッド.
注記1:mMethodオブジェクトは、前述のSystemServerのmainメソッドのMethodオブジェクトであり、invokeによってmainメソッドが呼び出されます.これでシステムサーバはmainメソッドを実行します.
新しいアプリケーションappの起動など、socketクライアントの接続要求をループします.
ここでは詳しくは説明しませんが、while(true)はクライアントのリクエストを絶えず待っています.
SOcketクライアントを呼び出すリクエスト者からのMehodオブジェクトメソッドの実行
ここで,1つの処理は,前述のMethodAndArgsCallerクラスにおけるrun()法の処理で解析された.
まとめ app_を通過プロセスはZygoteInitを起動する.main()関数. はまずserverSocketを登録しました. forkはSystemServerプロセスを開始し、nativeメソッドでbinderスレッドプールを開き、SytemServerに提供してプロセス間通信を容易にします. socketクライアントの接続要求 を待つ.
前の文章Androidシステム起動シリーズ---initプロセス、大体分析して、initプロセスの起動過程.最後にZygoteプロセスはapp_プロセスプロセスはJNIによってZygoteInitのmainメソッドを呼び出して開始される.この文章はZygoteプロセスが私たちのために何をしたかを分析します.(システムソース分析はAndroid 6.0.1に基づく)
Zygote機能
まずZygoteInitのmainメソッドを見てみましょう(/frameworks/base/core/java/com/android/internal/os/ZygoteInit.java)
public static void main(String argv[]) {
try {
RuntimeInit.enableDdms();
// Start profiling the zygote initialization.
SamplingProfilerIntegration.start();
boolean startSystemServer = false;
String socketName = "zygote";
String abiList = null;
for (int i = 1; i < argv.length; i++) {
if ("start-system-server".equals(argv[i])) {
startSystemServer = true;
} else if (argv[i].startsWith(ABI_LIST_ARG)) {
abiList = argv[i].substring(ABI_LIST_ARG.length());
} else if (argv[i].startsWith(SOCKET_NAME_ARG)) {
socketName = argv[i].substring(SOCKET_NAME_ARG.length());
} else {
throw new RuntimeException("Unknown command line argument: " + argv[i]);
}
}
if (abiList == null) {
throw new RuntimeException("No ABI list supplied.");
}
registerZygoteSocket(socketName); // 1
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_START,
SystemClock.uptimeMillis());
preload(); // 2
EventLog.writeEvent(LOG_BOOT_PROGRESS_PRELOAD_END,
SystemClock.uptimeMillis());
// Finish profiling the zygote initialization.
SamplingProfilerIntegration.writeZygoteSnapshot();
// Do an initial gc to clean up after startup
gcAndFinalize();
// Disable tracing so that forked processes do not inherit stale tracing tags from
// Zygote.
Trace.setTracingEnabled(false);
if (startSystemServer) {
startSystemServer(abiList, socketName); // 3
}
Log.i(TAG, "Accepting command socket connections");
runSelectLoop(abiList); // 4
closeServerSocket();
} catch (MethodAndArgsCaller caller) {
caller.run(); // 5
} catch (RuntimeException ex) {
Log.e(TAG, "Zygote died with exception", ex);
closeServerSocket();
throw ex;
}
}
SOcket通信のサービス・エンドの登録(registerZygoteSocket)
「zygote」という名前のsocketserverを登録します.
private static void registerZygoteSocket(String socketName) {
if (sServerSocket == null) {
int fileDesc;
final String fullSocketName = ANDROID_SOCKET_PREFIX + socketName;
try {
String env = System.getenv(fullSocketName);
fileDesc = Integer.parseInt(env);
} catch (RuntimeException ex) {
throw new RuntimeException(fullSocketName + " unset or invalid", ex);
}
try {
FileDescriptor fd = new FileDescriptor();
fd.setInt$(fileDesc);
sServerSocket = new LocalServerSocket(fd); // 1
} catch (IOException ex) {
throw new RuntimeException(
"Error binding to local socket '" + fileDesc + "'", ex);
}
}
}
注記1:serversocket静的オブジェクトを作成する
プリロード
static void preload() {
Log.d(TAG, "begin preload");
preloadClasses(); // class
preloadResources(); //
preloadOpenGL(); // OpenGL
preloadSharedLibraries(); // so : android、jnigraphics so
preloadTextResources(); //
// Ask the WebViewFactory to do any initialization that must run in the zygote process,
// for memory sharing purposes.
WebViewFactory.prepareWebViewInZygote();
Log.d(TAG, "end preload");
}
SystemServerシステムサービスの起動
/**
* Prepare the arguments and fork for the system server process.
*/
private static boolean startSystemServer(String abiList, String socketName)
throws MethodAndArgsCaller, RuntimeException {
.....
/* Hardcoded command line to start the system server */
////////////////////// 1
String args[] = {
"--setuid=1000",
"--setgid=1000",
"--setgroups=1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1018,1021,1032,3001,3002,3003,3006,3007",
"--capabilities=" + capabilities + "," + capabilities,
"--nice-name=system_server",
"--runtime-args",
"com.android.server.SystemServer",
};
ZygoteConnection.Arguments parsedArgs = null;
int pid;
try {
parsedArgs = new ZygoteConnection.Arguments(args);
ZygoteConnection.applyDebuggerSystemProperty(parsedArgs);
ZygoteConnection.applyInvokeWithSystemProperty(parsedArgs);
/* Request to fork the system server process */
////////////////////// 2
pid = Zygote.forkSystemServer(
parsedArgs.uid, parsedArgs.gid,
parsedArgs.gids,
parsedArgs.debugFlags,
null,
parsedArgs.permittedCapabilities,
parsedArgs.effectiveCapabilities);
} catch (IllegalArgumentException ex) {
throw new RuntimeException(ex);
}
/* For child process */
if (pid == 0) {
if (hasSecondZygote(abiList)) {
waitForSecondaryZygote(socketName);
}
////////////////////// 3
handleSystemServerProcess(parsedArgs);
}
return true;
}
a.注釈1:システムサーバを起動するいくつかのパラメータを設定するb.注釈2:パラメータforkに従ってシステム_サーバのプロセス
public static int forkSystemServer(int uid, int gid, int[] gids, int debugFlags,
int[][] rlimits, long permittedCapabilities, long effectiveCapabilities) {
VM_HOOKS.preFork();
int pid = nativeForkSystemServer(
uid, gid, gids, debugFlags, rlimits, permittedCapabilities, effectiveCapabilities);
// Enable tracing as soon as we enter the system_server.
if (pid == 0) {
Trace.setTracingEnabled(true);
}
VM_HOOKS.postForkCommon();
return pid;
}
nativeForkSystemServerメソッドはnativeローカルメソッドの役割であり、forkのSystemServerプロセスである.
c.注釈3:注釈2のpid=0でifの文がSystemServerプロセスで実行することを示すcomを起動する.android.server.SystemServerクラスのmainメソッド.
private static void handleSystemServerProcess(
ZygoteConnection.Arguments parsedArgs)
throws ZygoteInit.MethodAndArgsCaller {
.......
if (parsedArgs.invokeWith != null) {
String[] args = parsedArgs.remainingArgs;
........
WrapperInit.execApplication(parsedArgs.invokeWith,
parsedArgs.niceName, parsedArgs.targetSdkVersion,
VMRuntime.getCurrentInstructionSet(), null, args);
} else {
ClassLoader cl = null;
if (systemServerClasspath != null) {
cl = new PathClassLoader(systemServerClasspath, ClassLoader.getSystemClassLoader());
Thread.currentThread().setContextClassLoader(cl);
}
/*
* Pass the remaining arguments to SystemServer.
*/
//////////////////////////// 1
RuntimeInit.zygoteInit(parsedArgs.targetSdkVersion, parsedArgs.remainingArgs, cl);
}
}
注記1システムサーバのいくつかのパラメータをRuntimeInitに入力します.zygoteInitメソッド.もう一度見てみろzygoteInitメソッド:
public static final void zygoteInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
......
nativeZygoteInit(); /////////////////// 1
applicationInit(targetSdkVersion, argv, classLoader); ///////////////////////// 2
}
static void com_android_internal_os_RuntimeInit_nativeZygoteInit(JNIEnv* env, jobject clazz)
{
gCurRuntime->onZygoteInit();
}
onZygoteInitは虚関数で、その実装クラスはどこにあるのか、前の記事app_を覚えています.プロセスのapp_main.cppファイルにAppRuntimeクラスはありますかruntime.start()はZygoteプロセスを開始し,AppRutimeクラスはAndroid Runtimeを継承しonZygoteInitメソッドを実現した.virtual void onZygoteInit()
{
sp proc = ProcessState::self();
ALOGV("App process: starting thread pool.
");
proc->startThreadPool();
}
ここでprocは、binderのスレッドプールであり、後でbinderスレッドプールを詳細に分析し、プロセス間の通信に使用します.private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
.......
// Remaining arguments are passed to the start class's static main
invokeStaticMain(args.startClass, args.startArgs, classLoader);
}
invokeStaticMainメソッドを続行します.
private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader)
throws ZygoteInit.MethodAndArgsCaller {
Class> cl;
try {
///////////////////// 1
cl = Class.forName(className, true, classLoader);
} catch (ClassNotFoundException ex) {
throw new RuntimeException(
"Missing class when invoking static main " + className,
ex);
}
Method m;
try {
/////////////////// 2
m = cl.getMethod("main", new Class[] { String[].class });
} catch (NoSuchMethodException ex) {
throw new RuntimeException(
"Missing static main on " + className, ex);
} catch (SecurityException ex) {
throw new RuntimeException(
"Problem getting static main on " + className, ex);
}
int modifiers = m.getModifiers();
if (! (Modifier.isStatic(modifiers) && Modifier.isPublic(modifiers))) {
throw new RuntimeException(
"Main method is not public and static on " + className);
}
/////////////////// 3
throw new ZygoteInit.MethodAndArgsCaller(m, argv);
}
私たちは一緒に降りてclassNameに入るのがcomだと知っています.android.server.SystemServer注記1:Classを反射する.forNameはcomをロードします.android.server.SystemServerのSystemServerclassオブジェクト.注記2:SystemServerを介して.classオブジェクトのSystemServerのmainメソッドを取得するMethodオブジェクト.注釈3:この方法は終わっても実際にinvoke SystemServerのmain方法を反射するのではなくZygoteInitを投げ出した.MethodAndArgsCaller異常はmainメソッドのMethodオブジェクトとパラメータを入力します.明らかにこの異常類が処理したに違いない.じゃあどこを見つけるんだ?catchはこの異常情報を処理した.最終的には最初のZygoteInitで見ることができます.main()メソッド.
try{
......
} catch (MethodAndArgsCaller caller) {
caller.run(); // 5
}
public static class MethodAndArgsCaller extends Exception
implements Runnable {
/** method to call */
private final Method mMethod;
/** argument array */
private final String[] mArgs;
public MethodAndArgsCaller(Method method, String[] args) {
mMethod = method;
mArgs = args;
}
public void run() {
try {
mMethod.invoke(null, new Object[] { mArgs }); /////////// 1
} catch (IllegalAccessException ex) {
throw new RuntimeException(ex);
} catch (InvocationTargetException ex) {
Throwable cause = ex.getCause();
if (cause instanceof RuntimeException) {
throw (RuntimeException) cause;
} else if (cause instanceof Error) {
throw (Error) cause;
}
throw new RuntimeException(ex);
}
}
}
注記1:mMethodオブジェクトは、前述のSystemServerのmainメソッドのMethodオブジェクトであり、invokeによってmainメソッドが呼び出されます.これでシステムサーバはmainメソッドを実行します.
新しいアプリケーションappの起動など、socketクライアントの接続要求をループします.
ここでは詳しくは説明しませんが、while(true)はクライアントのリクエストを絶えず待っています.
SOcketクライアントを呼び出すリクエスト者からのMehodオブジェクトメソッドの実行
ここで,1つの処理は,前述のMethodAndArgsCallerクラスにおけるrun()法の処理で解析された.
まとめ