JVM是如何调用方法的?

调用方法分为三部分,

第一部分:如何找到类和方法?

第二部分:线程如何知道该执行哪些方法?

第三部分:执行完某个方法后的如何处理?

1:如:

Test的类文件结构中有一项为field_info,这一项会存储类中声明的变量,field_info中由name_index和descriptor_index分别指向简单名称以及字段和方法的描述符。简单名称就比如是msg,描述符比简单名称复杂的多,它不仅需要指明是哪个类,对于方法来说,它还需要存储方法的参数和返回值。

对于上面这种例子,根据描述符中存储的ResultMsg的全限定名,找到这个类的类信息,将其加载进方法区中。(我们可以去获取这个类的二进制字节流,将这个字节流所代表的静态存储结构转化为方法区的运行时数据结构,并在内存中生成一个代表这个类的java.lang.Class对象,作为方法区这个类的各种数据的访问入口)。

而后在调用msg.getResultCode方法时,是在msg的类文件结构中有一项method_info,会存储方法的相关信息。

2:如图:


如果此时有一个线程执行sayHello方法,则该线程中的java虚拟机栈中就会有四个栈帧,第一个栈帧1是sayHello。第二个栈帧2是new ResultMsg(),第三个栈帧3是System.out.println,第四个栈帧4是getResultCode(后两者都没有调用其他方法),我们可以认为栈帧4就是当前栈帧了。栈帧的生成是从方法被调用开始的,知道这个方法被使用完,就会出栈。

3:方法执行完后有两种方式结束该方法的调用,一种是因为异常退出(没有捕捉某种异常导致,另一种是故意抛出的异常),另一种是正常退出。

第一种称为异常完成出口,不会给上层调用者任何返回值。

第二种称为正常完成出口,可能会有返回值返回给上层调用者。

两种都需要返回到方法被调用的位置,因此需要在栈帧中存访一些信息来帮助记住上层方法的调用状态。一般来说正常退出时,可以使用PC计数器的值作为返回地址,栈帧中很可能会存放这个计数器值。

你可能感兴趣的:(JVM是如何调用方法的?)