JVM虚拟机结构与机制(2)

         解析(可选):主要是把类的常量池中的符号引用解析为直接引用,这一步可以在用到相应的引用时再解析。

   3)初始化:

      初始化类中的静态变量,并执行类中的static代码、构造函数。

      JVM规范严格定义了何时需要对类进行初始化:

        a.通过new关键字、反射、clone、反序列化机制实例化对象时。

        b.调用类的静态方法。

        c.通过反射调用类的方法时。

        d.初始化该类的子类时(初始化子类前其父类必须已经被初始化)。

        e.JVM启动时被标记为启动类的类(简单理解为具有main方法的类)。

三、Java栈(Java Stack)

   Java栈由栈帧组成,一个帧对应一个方法调用。调用方法时压入栈帧,方法返回时弹出栈帧并抛弃。Java栈的主要任务是存储方法参数、局部变量、中间运算结果,Java栈是线程私有的,这就保证了线程安全性,使得程序员无需考虑栈同步访问的问题,只有线程本身可以访问它自己的局部变量区。

   它分为三部分:局部变量区、操作数栈、帧数据区

      1.局部变量区

       局部变量区是以字长为单位的数组,在这里byte、short、char类型会被转换成int类型存储,除了long和double类型占两个字长以外,其余类型都只占用一个字长。特别地,boolean类型在编译时会被转换成int或byte类型,boolean数组会被当做byte类型数组来处理。

2.操作数栈

     操作数栈和局部变量区一样,操作数栈也被组织成一个以字长为单位的数组。但和前者不同的是,它不是通过索引来访问的,而是通过入栈和出栈来访问的。可把操作数栈理解为存储计算时,临时数据的存储区域。

     3.帧数据区

     当JVM执行到需要常量池数据的指令时,它都会通过帧数据区中指向常量池的指针来访问它除了处理常量池解析外,帧里的数据还要处理java方法的正常结束和异常终止。如果是通过return正常结束,则当前栈帧从Java栈中弹出,恢复发起调用的方法的栈。如果方法又返回值,JVM会把返回值压入到发起调用方法的操作数栈。

为了处理java方法中的异常情况,帧数据区还必须保存一个对此方法异常引用表的引用。当异常抛出时,JVM给catch块中的代码。如果没发现,方法立即终止,然后JVM用帧区数据的信息恢复发起调用的方法的帧。然后再发起调用方法的上下文重新抛出同样的异常。

四、本地方法栈(Native Method Stack)

本地方法栈类似于Java栈,主要存储了本地方法调用的状态。在Sun JDK中,本地方法栈和Java栈是同一个。

五、方法区(Method Area)

方法区是系统分配的一个内存逻辑区域,是用来存储类型信息的(类型信息可理解为类的描述信息)。方法区主要有以下几个特点: 
      1.方法区是线程安全的。由于所有的线程都共享方法区,所以,方法区里的数据访问必须被设计成线程安全的。例如,假如同时有两个线程都企图访问方法区中的同一个类,而这个类还没有被装入JVM,那么只允许一个线程去装载它,而其它线程必须等待 
      2.方法区的大小不必是固定的,JVM可根据应用需要动态调整。同时,方法区也不一定是连续的,方法区可以在一个堆(甚至是JVM自己的堆)中自由分配。 
      3.方法区也可被垃圾收集,当某个类不在被使用(不可触及)时,JVM将卸载这个类,进行垃圾收集 

六、堆(Heap)

内容版权声明:除非注明,否则皆为本站原创文章。

转载注明出处:https://www.heiqu.com/09400f6cac3e1f1c7bfca1ea9b47b450.html