设为首页 加入收藏

TOP

JVM虚拟机结构与机制(一)
2017-04-21 10:23:13 】 浏览:349
Tags:JVM 虚拟 结构 机制

JVM(Java Virtual Machine)在研究JVM的过程中会发现,其实JVM本身就是一个计算机体系结构,很多原理和我们平时的硬件、微机原理、操作系统都有十分相似的地方,所以学习JVM本身也是加深自我对计算机结构认识的一个很好的途径。


一、JVM结构


  下图展示了JVM的主要结构:


   


   1.从上图可以看出,JVM主要由类加载器子系统、运行时数据区(内存空间)、执行引擎以及与本地方法接口等组成。其中运行时数据区又由方法区、堆、Java栈、PC寄存器、本地方法栈组成。


   2.从上图中还可以看出,在内存空间中方法区和堆是所有Java线程共享的,而Java栈、本地方法栈、PC寄存器则由每个线程私有。


   3.Java语言具有跨平台的特性,这也是由JVM来实现的。更准确地说,是Sun利用JVM在不同平台上的实现帮我们把平台相关性的问题给解决了,这就好比是HTML语言可以在不同厂商的浏览器上呈现元素(虽然某些浏览器在对W3C标准的支持上还有一些问题)。同时,Java语言支持通过JNI(Java Native Interface)来实现本地方法的调用,但是需要注意到,如果你在Java程序用调用了本地方法,那么你的程序就很可能不再具有跨平台性,即本地方法会破坏平台无关性。


 二、类加载器子系统(Class Loader)


   类加载器子系统负责加载编译好的.class字节码文件并装入内存,使JVM可以实例化或以其它方式使用加载后的类。


  1.ClassLoader的分类:


    1)启动类加载器(BootStrap Class Loader):负责加载rt.jar文件中所有的Java类,Java的核心类都是由该ClassLoader加载。在Sun JDK中,这个类加载器是由C++实现的,并且在Java语言中无法获得它的引用。


    2)扩展类加载器(Extension Class Loader):负责加载一些扩展功能的jar包。


    3)系统类加载器(System Class Loader):负责加载启动参数中指定的Classpath中的jar包及目录。


    4)用户自定义类加载器(User Defined Class Loader):由用户自定义类的加载规则,可以手动控制加载过程中的步骤。


  2.ClassLoader的工作原理:


     类加载分为装载、链接、初始化三步。


    1)装载:


       通过类的全名和ClassLoader加载类,主要是将指定的.class文件加载至JVM。当类被加载以后,在JVM内部就以“类的全限定名+ClassLoader实例ID”来标明类。


      在内存中,ClassLoader实例和类的实例都位于堆中,它们的类信息都位于方法区。装载过程采用了一种被称为“双亲委派模型(Parent Delegation Model)”的方式,当一个ClassLoader要加载类时,它会先请求它的双亲ClassLoader(其实这里只有两个ClassLoader,所以称为父ClassLoader可能更容易理解)加载类,而它的双亲ClassLoader会继续把加载请求提交再上一级的ClassLoader,直到启动类加载器。只有其双亲ClassLoader无法加载指定的类时,它才会自己加载类。双亲委派模型是JVM的第一道安全防线,它保证了类的安全加载,这里同时依赖了类加载器隔离的原理:不同类加载器 加载的类之间是无法直接交互的,即使是同一个类,被不同的ClassLoader加载,它们也无法感知到彼此的存在。


   2) 链接:


      链接的任务是把二进制的类型信息合并到JVM运行时状态中去。


      链接分为三部分:


         验证:校验.class文件的正确性,确保该文件是符合规范定义的。


         准备:为类分配内存,同时初始化类中的静态变量赋值为默认值。


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


   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会把返回值压入到发起调用方法的操作数栈。


 


&nb

首页 上一页 1 2 下一页 尾页 1/2/2
】【打印繁体】【投稿】【收藏】 【推荐】【举报】【评论】 【关闭】 【返回顶部
上一篇JNDI在Java Web工程中的配置 下一篇使用Visual Studio Code编写Swift..

最新文章

热门文章

Hot 文章

Python

C 语言

C++基础

大数据基础

linux编程基础

C/C++面试题目