startThreadPool();}这个分支到此先不往下跟踪了,和启动的过程关系不大了。下面我们回到RuntimeInit.java看下applicationInit:private static void applicationInit(int targetSdkVersion, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller { // 设置关闭引用程序是是否调用AppRuntime.onExit(),默认调用 nativeSetExitWithoutCleanup(true); ...... // 传递参数,并调用类的main方法 invokeStaticMain(args.startClass, args.startArgs, classLoader); }关键方法是invokeStaticMain,执行类的main方法,这个类在前面的startSystemServer里面有参数传递,具体是这样的: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", };所以这个类就是SystemServer,调用的就是他的main方法。下面看看invokeStaticMain内部:private static void invokeStaticMain(String className, String[] argv, ClassLoader classLoader) throws ZygoteInit.MethodAndArgsCaller { Class cl; // 通过反射获取类名 try { cl = Class.forName(className, true, classLoader); } catch (ClassNotFoundException ex) { throw new RuntimeException( "Missing class when invoking static main " + className, ex); } // 获取该类的main方法 Method m; try { 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); } /* * This throw gets caught in ZygoteInit.main(), which responds * by invoking the exception's run() method. This arrangement * clears up all the stack frames that were required in setting * up the process. */ // 抛出异常 throw new ZygoteInit.MethodAndArgsCaller(m, argv);}看到这里一定会奇怪,为何在此处抛出一个异常:throw new ZygoteInit.MethodAndArgsCaller(m, argv);,这里我们需要往前回溯看看,到底在哪里捕获的异常。结果是发现在ZygoteInit.java的main中进行的捕获:try { ...... if (startSystemServer) { startSystemServer(abiList, socketName); } ......} catch (MethodAndArgsCaller caller) { caller.run();}调用的起始也是从这里开始的,好吧,我们看看捕获到异常之后做了什么。调用了caller.run()。抛出异常的时候已经new了一个throw new ZygoteInit.MethodAndArgsCaller(m, argv);这个对象了,并且参数给出的就是SystemServer类的main方法,那么继续看ZygoteInit.MethodAndArgsCaller: 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 }); } 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); } } }run方法就是调用了一下这个方法,也就是调用了SystemServer的main方法,直接跳到main方法执行了。但是为何这么做呢?这里有个疑问。其实仔细想想也挺有意思。这一串调用从startSystemServer开始执行了比较深了,每次执行函数方法的时候都会伴随着出现局部变量,那么就会直接开辟在栈上,之后的SystemServer又是个常驻不退出的进程,那么栈上面的这些空间也就意味着并不会释放,而启动过程只会执行一次,后面没用了,这些东西没有清理就一直存在。这里直接抛出异常后,在startSystemServer这个最初的位置捕获,会导致异常发生后直接跳到捕获的地方,之前所有的栈全部被清空。这下子明白了吧。google很聪明的利用了异常的做法回溯了栈,释放不用的内存。真是非常聪明! 10-17 07:46