我是Java和Android的初学者,在阅读Zygote init代码后我感到困惑.
在Zygote分配一个子进程后,在它结束时invokeStaticMain,它会抛出一个
throw new ZygoteInit.MethodAndArgsCaller(m, argv)
Run Code Online (Sandbox Code Playgroud)
这是ZygoteInit.main由执行子进程工作的catch块处理的
catch (MethodAndArgsCaller caller) {
caller.run();
}
Run Code Online (Sandbox Code Playgroud)
评论throw new ZygoteInit.MethodAndArgsCaller说它将清理设置过程所需的所有堆栈帧.
但我无法弄清楚如何清理堆栈帧.我检查了相关的SO问题,什么是ZygoteInit调用?但问题和答案都没有解释清理工作.
异常会导致堆栈回收工作吗?
在Java中,如果方法通过执行return语句完成,或者通过成功执行声明为的方法的最后一行void,则称其正常完成.
当方法正常完成时,JVM(Java虚拟机)弹出返回方法的堆栈帧,并在调用方法中的方法调用之后继续执行.调用方法成为当前方法,其堆栈帧成为当前帧.
如果一个方法抛出一个它没有捕获自己的异常,那么它就会被突然完成.突然完成的方法不会返回值,尽管它们确实传递了异常对象,例如java.io.IOException.
当一个方法突然完成时,意味着它抛出了一个它没有捕获到它的异常,JVM会弹出该方法的堆栈帧.然后,JVM检查调用堆栈中的下一个方法,以获取处理抛出异常的catch子句.这个循环一直持续到两件事之一发生:
找到具有适当catch子句的方法,其中JVM将使该方法的堆栈帧为当前并在catch子句中的第一个语句处继续执行.
JVM将检查public static void main(String[] args)调用堆栈,当它找不到正确的catch子句时,它将弹出main堆栈帧.调用堆栈现在为空,因为它main是线程调用的第一个方法.这会导致一个未捕获的异常,它将由一个默认处理程序处理,并导致该线程死亡.在大多数JRE(Java运行时环境)中,未捕获异常的默认处理程序将在线程死亡时打印出堆栈跟踪.
异常或突然完成的方法可用于控制程序的流程.虽然99.99%的时间使用控制流异常被认为是反模式,但仍有0.01%的时间可能需要或可能大幅改进程序.
在整个com.android.internal.os.ZygoteInit班级中可以看到使用异常作为控制流程 .主要通过使用以下例外:
/**
* Helper exception class which holds a method and arguments and
* can call them. This is used as part of a trampoline to get rid of
* the initial process setup stack frames.
*/
public static class MethodAndArgsCaller extends Exception
implements Runnable { ... }
Run Code Online (Sandbox Code Playgroud)
当方法的文档说明"这被用作蹦床的一部分以摆脱初始过程设置堆栈帧".我认为trampoline这个术语指的是我上面提到的,关于JVM弹出堆栈帧和检查调用堆栈上的方法,直到找到正确的catch子句.蹦床的另一个术语可能是传播.
到目前为止我发现的唯一一个捕获ZygoteInit.MethodAndArgsCaller异常ZygoteInit的main方法是类' 方法,它似乎是中央控件.但是,我在com.android.internal.os.RuntimeInit类中发现了许多throws ZygoteInit.MethodAndArgsCaller声明中的方法.意思是,这些方法中调用的方法抛出或传播MethodAndArgsCaller异常.谁知道它走了多远?
我不是Android,Java或Zygote过程的专家,我不知道作者,所以我只能根据我研究的内容和Android源代码来假设.我希望我帮助解决了一些问题,如果需要更多帮助,请告诉我.
| 归档时间: |
|
| 查看次数: |
460 次 |
| 最近记录: |