Java虚拟机的体系结构

来源:互联网 发布:java最新版本 编辑:程序博客网 时间:2024/06/06 12:34

这里写图片描述
在java虚拟机中,关于被装载类型的信息存储在一个逻辑上被称为方法区的内存中。当虚拟机装载某个类型时,它使用类装载器定位相应的class文件,然后读入这个class文件—一个线性二进制数据流—然后将它传输到虚拟机中,紧接着虚拟机提取其中的类型信息,并将这些信息存储到方法区。该类型中的类(静态)变量同样也是存储在方法区中。

方法区

方法区包括类型信息

  • 这个类型的权限定名
  • 这个类型的直接超类的全限定名(除非这个类型是java.lang.Object,它没有超类)
  • 这个类型是类类型还是接口类型
  • 这个类型的访问修饰符
  • 任何直接超接口的全限定名

除了这些还包括

  • 该类型的常量池
  • 字段信息: 对于类型中声明的每一个字段,方法区中必须保存下面的信息。除此之外,这些字段在类或者接口中的声明顺序也必须保存。下面是字段信息的清单:
    字段名
    字段的类型
    字段的修饰符
  • 方法信息: 对于类型中声明的每一个方法,方法区中必须保存下面的信息。和字段一样,这些方法在类或者接口中的声明顺序也必须保存。下面是方法信息的清单:
    方法名
    方法的返回类型(或void)
    方法参数的数量和类型(按声明顺序)
    方法的修饰符
    除上面的清单中列出的条目之外,如果某个方法不是抽象的和本地的,它还必须保存下列信息:
    方法的字节码
    操作数栈和该方法中的局部变量区的大小
    异常表
  • 除了常量以外的所有类(静态)变量: 类变量是由所有类实例所共享的,但是即使没有任何实例,它也可以被访问。这些变量只与类相关—而非实例,因此它们总是作为类型信息的一部分而存储在方法区。除了在类中声明的编译时常量外,虚拟机在使用某个类之前,必须在方法区中为这些类变量分配空间。
    而编译时常量(就是那些用final声明以及用编译时已知的值初始化的类变量)则和一般的类变量的处理方式不同,每个使用编译时常量的类型都会复制它的所有常量到自己的常量池中,或嵌入到它的字节码流中。作为常量池或字节码流的一部分,编译时常量保存在方法区中—就和一般的类变量一样。但是当一般的类变量作为声明它们的类型的一部分数据而保存的时候,编译时常量作为使用它们的类型的一部分而保存。

  • 一个到类ClassLoader的引用

  • 一个到Class类的引用

Java程序运行时创建的所有类实例或数组都放在同一个堆中。

Java栈

每当启动一个新线程时,Java虚拟机都会为它分配一个Java栈。Java栈以帧为单位保存线程的运行状态。虚拟机只会直接对Java栈执行两种操作:以帧为单位的压栈或出栈。
某个线程正在执行的方法被称为该线程的当前方法,当前方法使用的栈帧为当前帧,当前方法所属的类称为当前类,当前类的常量池称为当前常量池。
每当线程调用一个Java方法时,虚拟机都会在该线程的Java栈中压入一个新帧。而这个新帧自然就成为了当前帧。在执行这个方法时,它使用这个帧来存储参数、局部变量、中间运算结果等等数据。

栈帧由三部分组成:局部变量区,操作数栈和帧数据区。
局部变量区包含对应方法的参数和局部变量。
当虚拟机调用一个方法时,它从对应类的类型信息中得到此方法的局部变量区和操作数栈的大小,并据此分配栈帧内存,然后压入Java栈中。


Java面向对象基础
Java面向对象之继承
Java面向对象之多态
Java面向对象之修饰符

0 0
原创粉丝点击