JVM虚拟机工作原理

来源:互联网 发布:java log4j 中文乱码 编辑:程序博客网 时间:2024/05/17 07:50

一,类加载器
1.层级结构
类加载器被组织成一种层级结构关系,也就是父子关系,其中,BootStrap是所有类加载器的父类,如下图所示:
这里写图片描述

BootStrap classloader
当运行java虚拟机时,这个类加载器被创建,它加载一些基本的java API,包括Object这个类,需要注意的是,这个类加载器不是java语言写的,而是C/C++语言写的
Extension classloader
这个加载器加载除了基本API之外的一些扩展类,包括一些与安全性能相关的类
System classloader
它加载应用程序的类,也就是classpath中配置的类
User-Defined classloader
这是开发人员通过扩展ClassLoader类定义的自定义加载器,加载程序员定义的一些类

委派模式
仔细看上面的层次结构,当JVM加载一个类的时候,下层的加载器会将任务委托给上一层类加载器,上一层加载器检查它的命名空间中是否已经加载了这个类,如果已经加载,直接使用这个类,如果没有加载,继续往上委托直到顶部,检查完了之后,按照相反的顺序进行加载,如果BootStrap加载器找不到这个类,则往下委托,直到找到类文件,对于某个特定的类加载器来说,一个java类只能被载入一次,也就是说在java虚拟机中,类的完整标识是(ClassLoader,package,className),一个类可以被不同的加载器加载。

这里写图片描述

可见性限制
下层的加载器能够看到上层加载器中的类,反之则不行,也就是是说委托只能从下到上。

不允许卸载类
类加载器可以加载一个类,但是它不能卸载一个类,但是类加载器可以被删除或者被创建

当类加载完毕之后,JVM继续按照下图完成其他工作:

这里写图片描述

二,运行数据区域
Runtime Data Areas:当运行一个JVM示例时,系统将分配给它一块内存区域,这一内存区域由JVM自己来管理,从这一块内存中分出一块用来存储一些运行数据,例如创建的对象,传递给方法的参数,局部变量,返回值等等。分出来的这一块就称为运行数据区域,运行数据区域可以划分为6大块::java栈,程序计数器(PC寄存器),本地方法栈,java堆,方法区域,运行常量池,运行常量池本应该属于方法区,但是由于其重要性,JVM规范将其独立出来说明,其中,前面3块区域(PC寄存器,java栈,本地方法栈)是每个线程独有的,后三者则是整个JVM实例中所有线程共有的,这流大块如下图所示:
这里写图片描述

PC计数器
每一个线程都有一个PC计数器,当线程启动(start)时,PC计数器被创建,这个计数器存放当前正在被执行的字节码指令的地址
java栈
同样的,java栈也是每个线程独有,线程启动时创建,这个栈中存放着一系列的栈帧,JVM只能进行压入(push)和(pop)栈帧两种操作,每当调用一个方法时,JVM就往栈里压入一个栈帧,方法结束返回弹出栈帧,如果方法执行时出现异常,可以调用printStackTrace等方法来查看栈的情况,栈的示意图如下:
这里写图片描述

每个栈帧包含三个部分:本地变量数组,操作数栈,方法所属类的常量池引用

三,执行引擎
类加载器将字节码载入内存之后,执行引擎以java字节码指令为单元,读取java字节码,问题是,现在的java字节码机器的hi读不懂的,因此还必须要想办法将字节码转化成平台相关的机器码,这个过程可以由解释器执行,也可以由即时编译器来完成

这里写图片描述

0 0
原创粉丝点击