java虚拟机基础知识大全 java虚拟机运行原理( 六 )


在JDK 9中引入的Java模块化系统(Java,JPMS)是对Java技术的一次重要升级,为了能够实现模块化的关键目标——可配置的封装隔离机制,Java虚拟机对类加载架构也做出了相应的变动调整,才使模块化系统得以顺利地运作 。
·JAR文件在类路径的访问规则:所有类路径下的JAR文件及其他资源文件,都被视为自动打包在一个匿名模块( )里,这个匿名模块几乎是没有任何隔离的,它可以看到和使用类路径上所有的包、JDK系统模块中所有的导出包,以及模块路径上所有模块中导出的包 。
·模块在模块路径的访问规则:模块路径下的具名模块(Named )只能访问到它依赖定义中列明依赖的模块和包,匿名模块里所有的内容对具名模块来说都是不可见的,即具名模块看不见传统JAR包的内容 。
·JAR文件在模块路径的访问规则:如果把一个传统的、不包含模块定义的JAR文件放置到模块路径中,它就会变成一个自动模块( ) 。尽管不包含-info.class,但自动模块将默认依赖于整个模块路径中的所有模块,因此可以访问到所有模块导出的包,自动模块也默认导出自己所有的包 。
JDK9以后,扩展类加载器( Class )被平台类加载器( )取代 。
当平台及应用程序类加载器收到类加载请求,在委派给父加载器加载前,要先判断该类是否能够归属到某一个系统模块中,如果可以找到这样的归属关系,就要优先委派给负责那个模块的加载器完成加载,也许这可以算是对双亲委派的第四次破坏 。
Java虚拟机以方法作为最基本的执行单元,“栈帧”(Stack Frame)则是用于支持虚拟机进行方法调用和方法执行背后的数据结构,它也是虚拟机运行时数据区中的虚拟机栈( Stack)[插图]的栈元素 。
栈帧存储了方法的局部变量表、操作数栈、动态连接和方法返回地址等信息 。
每一个方法从调用开始至执行结束的过程,都对应着一个栈帧在虚拟机栈里面从入栈到出栈的过程 。
局部变量表(LocalTable)是一组变量值的存储空间,用于存放方法参数和方法内部定义的局部变量 。在Java程序被编译为Class文件时,就在方法的Code属性的数据项中确定了该方法所需分配的局部变量表的最大容量 。
一个变量槽可以存放一个32位以内的数据类型,Java中占用不超过32位存储空间的数据类型有、byte、char、short、int、float、[插图]和这8种类型 。
第7种类型表示对一个对象实例的引用,虚拟机实现至少都应当能通过这个引用做到两件事情,一是从根据引用直接或间接地查找到对象在Java堆中的数据存放的起始地址或索引,二是根据引用直接或间接地查找到对象所属数据类型在方法区中的存储的类型信息,否则将无法实现《Java语言规范》中定义的语法约定 。
当一个方法被调用时,Java虚拟机会使用局部变量表来完成参数值到参数变量列表的传递过程,即实参到形参的传递 。如果执行的是实例方法(没有被修饰的方法),那局部变量表中第0位索引的变量槽默认是用于传递方法所属对象实例的引用,在方法中可以通过关键字“this”来访问到这个隐含的参数 。
操作数栈( Stack)也常被称为操作栈,它是一个后入先出(Last In First Out,LIFO)栈 。同局部变量表一样,操作数栈的最大深度也在编译的时候被写入到Code属性的数据项之中 。
Java虚拟机的解释执行引擎被称为“基于栈的执行引擎”,里面的“栈”就是操作数栈 。
每个栈帧都包含一个指向运行时常量池[插图]中该栈帧所属方法的引用,持有这个引用是为了支持方法调用过程中的动态连接( ) 。