您的位置:首页 > 编程语言 > Java开发

Java基础之JVM运行机制

2017-04-12 17:01 375 查看
Java基础之JVM运行机制

 

 

Java Virtual Machine简称JVM,它是一种规范,是一种计算的仿真。我们知道java语言是跨平台的,而JVM是java跨平台的关键之所在。JVM上执行java字节码,执行时这些字节码可以解释成具体平台的机器码,因此java拥有“一次编译,处处运行”这一跨平台能力。

 

     JVM运行机制和物理结构可以参考以下两张图所示:



 

    



从上面我们可以看出java运行主要分几个步骤:

 

一、java源码编译。

 

二、类加载。

 

三、类执行。

 

 

步骤一:编译

 

将java代码编译成字节码是类加载前的一个必要步骤,那么Java源码编译过程究竟是怎样的呢?我们先看下面的一张图:

 

     



 

 

     输入是java源代码,输出是JVM上可运行的字节码,而上图中的符号表主要是存贮和标识符有关的Token信息。这个编译过程分三个阶段:分析与输入到符号表、注解处理、语义分析与生成字节码文件,其流程请参考下图:

 

     



 

 

     最后生成的字节码文件中包含结构信息、元数据、方法信息。

 

1、结构信息:class文件格式版本号和各部分的数量与大小信息。

 

2、元数据:指Java源码中声明与常量的信息,包含类/继承的超类/实现的接口等声明信息、域与方法声明信息、常量池。

 

3、方法信息:对应Java源码中语句和表达式对应的信息,包含字节码、异常处理器表、求值栈的类型记录、调试符号信息、求值栈与局部变量区大小。

 

 

 

步骤二:加载

 

     我们知道,java类必须加载到JVM中才能运行,这个工作由类加载器完成,这个实际上就是把.class文件从硬盘读到内存里。其实类加载器也是一个类,名字叫bootstrap classloader,java运行需要的所有类(jre/lib/rt.jar)都是由它加载。该类由c++语言编写,可以独立运行,是JVM运行的起点。类的加载可通过两种方式实现,第一种是显式加载,另一种则是隐式加载。

 

显式加载。

 

显式加载类的实施方式比较多,比如加载类Demo,我们可以使用Class类的forName方法进行加载,即Class.forName(“Demo”);这个语句是简写形式,完整写法是Class.forName(“Demo”,true,this.getClass().getClassLoader());当然,java程序员对程序控制权的迷恋向来很深,你大可以自己定义一个加载类。方法如下:

 

public class CustomClassLoader extends URLClassLoader{

 

public CustomClassLoader(){

 

super(new URL[0]);

 

}

 

}

 

         CustomClassLoader classLoader=new CustomClassLoader();

 

         classLoader.loadClass(“Demo”);

 

     这里CustomClassLoader继承了JDK中核心包中的类加载器。

 

隐式加载。

其实我们很少去显式加载。

Demo demo=new Demo();

 

程序运行到这句代码发现内存里还没有Demo类,这时候JVM就会请求加载当前类的类加载器来加载该类。这里需要注意的是只有该句代码的确能有效执行时才会去加载对应类,否则是不会加载的,这样做的目的是尽可能少地加载类,减少内存资源的开销。

 

加载类是一种树状结构,加载时首先要从叶子节点往根部检查,检查类是否已经被加载,如果检查到某个classLoader已加载则视为已加载此类。为保证此类所有classLoader加载一次,加载类会从根往叶子节点逐级加载此类。具体检查和加载顺序如下图所示:



 

 

 

     步骤三:执行

 

字节码加载到JVM后执行,具体执行步骤我们可以参考下图:

 



 

我们知道,JVM是基于栈的体系结构来执行JVM字节码的。具体来说先创建线程,产生程序计数器(PC)和栈(Stack)。其中程序计数器存放下一条要执行的指令在方法内的偏移量,栈中则存放一个个栈帧,每个栈帧对应每个方法的每次调用;另外栈帧是由局部变量区和操作数栈两个部分组成,局部变量区用于存放方法中的局部变量和参数,操作数栈用于存放方法执行过程中所产生的中间结果。

 

 

Java基础之JVM运行机制

 

作者:忆辛

 

Java Virtual Machine简称JVM,它是一种规范,是一种计算的仿真。我们知道java语言是跨平台的,而JVM是java跨平台的关键之所在。JVM上执行java字节码,执行时这些字节码可以解释成具体平台的机器码,因此java拥有“一次编译,处处运行”这一跨平台能力。

 

     JVM运行机制和物理结构可以参考以下两张图所示:



 

    



从上面我们可以看出java运行主要分几个步骤:

 

一、java源码编译。

 

二、类加载。

 

三、类执行。

 

 

步骤一:编译

 

将java代码编译成字节码是类加载前的一个必要步骤,那么Java源码编译过程究竟是怎样的呢?我们先看下面的一张图:

 

     



 

 

     输入是java源代码,输出是JVM上可运行的字节码,而上图中的符号表主要是存贮和标识符有关的Token信息。这个编译过程分三个阶段:分析与输入到符号表、注解处理、语义分析与生成字节码文件,其流程请参考下图:

 

     



 

 

     最后生成的字节码文件中包含结构信息、元数据、方法信息。

 

1、结构信息:class文件格式版本号和各部分的数量与大小信息。

 

2、元数据:指Java源码中声明与常量的信息,包含类/继承的超类/实现的接口等声明信息、域与方法声明信息、常量池。

 

3、方法信息:对应Java源码中语句和表达式对应的信息,包含字节码、异常处理器表、求值栈的类型记录、调试符号信息、求值栈与局部变量区大小。

 

 

 

步骤二:加载

 

     我们知道,java类必须加载到JVM中才能运行,这个工作由类加载器完成,这个实际上就是把.class文件从硬盘读到内存里。其实类加载器也是一个类,名字叫bootstrap classloader,java运行需要的所有类(jre/lib/rt.jar)都是由它加载。该类由c++语言编写,可以独立运行,是JVM运行的起点。类的加载可通过两种方式实现,第一种是显式加载,另一种则是隐式加载。

 

显式加载。

 

显式加载类的实施方式比较多,比如加载类Demo,我们可以使用Class类的forName方法进行加载,即Class.forName(“Demo”);这个语句是简写形式,完整写法是Class.forName(“Demo”,true,this.getClass().getClassLoader());当然,java程序员对程序控制权的迷恋向来很深,你大可以自己定义一个加载类。方法如下:

 

public class CustomClassLoader extends URLClassLoader{

 

public CustomClassLoader(){

 

super(new URL[0]);

 

}

 

}

 

         CustomClassLoader classLoader=new CustomClassLoader();

 

         classLoader.loadClass(“Demo”);

 

     这里CustomClassLoader继承了JDK中核心包中的类加载器。

 

隐式加载。

其实我们很少去显式加载。

Demo demo=new Demo();

 

程序运行到这句代码发现内存里还没有Demo类,这时候JVM就会请求加载当前类的类加载器来加载该类。这里需要注意的是只有该句代码的确能有效执行时才会去加载对应类,否则是不会加载的,这样做的目的是尽可能少地加载类,减少内存资源的开销。

 

加载类是一种树状结构,加载时首先要从叶子节点往根部检查,检查类是否已经被加载,如果检查到某个classLoader已加载则视为已加载此类。为保证此类所有classLoader加载一次,加载类会从根往叶子节点逐级加载此类。具体检查和加载顺序如下图所示:



 

 

 

     步骤三:执行

 

字节码加载到JVM后执行,具体执行步骤我们可以参考下图:

 



 

我们知道,JVM是基于栈的体系结构来执行JVM字节码的。具体来说先创建线程,产生程序计数器(PC)和栈(Stack)。其中程序计数器存放下一条要执行的指令在方法内的偏移量,栈中则存放一个个栈帧,每个栈帧对应每个方法的每次调用;另外栈帧是由局部变量区和操作数栈两个部分组成,局部变量区用于存放方法中的局部变量和参数,操作数栈用于存放方法执行过程中所产生的中间结果。

 

 

 

作者:忆辛,写于羊城,于2015年02月05日 10点57分发表在ITeye网站,任何单位和个人未经作者书面许可,禁止转载、复制本文全文或文章的任何部分。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: