【JVM系列】一步步解析java执行内幕

        对于任何一门语言,要想达到精通的水平,研究它的执行原理(或者叫底层机制)不失为一种良好的方式。在本篇文章中,将重点研究java源代码的执行原理,即从程java

序员编写JAVA源代码,到最终造成产品,在整个过程当中,都经历了什么?每一步又是怎么执行的?执行原理又是什么?.....编程

       固然,本篇文章的粒度可能稍微侧重于宏观方面,更细粒度的技术分析,须要在接下来的该系列文章中与你们分享....bootstrap

一 编写java源程序工具


  java源文件:指存储java源码的文件;开发工具

当前比较主流的JAVA IDE?优化

(1)Intellij IDEA(首推荐)编码

(2)Eclipsespa

先来看看以下代码:操作系统

//MyTest被public修饰,故存储该java源码的文件名为MyTest
public class MyTest {
    public static void main(String[] args){
        System.out.println("Test Java execute process.");
    }
}

//因为MyTest被public修饰了,故Class A不能用public修饰
class A{}
//因为MyTest被public修饰了,故Class B不能用public修饰
class B{}

(1)java源文件名就是该源文件中public类的名称线程

(2)一个java源文件能够包含多个类,但只容许一个类为public

二 编译java源代码


      当java源程序编码结束后,就须要编译器编译,安装好jdk后,咱们打开jdk目录,有两个.exe文件,

即javac.exe(编译源代码,即.java文件)和java.exe(执行字节码,即.class文件)

1.切换到MyTest.java文件夹

2.javac.exe编译MyTest.java

编译后,发现e:\Blogs 目录多了以class为后缀的文件:A.class,B.class和MyTest.class

Tip:当javac.exe编译java源代码时,java源代码有几个类,就会编译成一个对应的字节码文件(.class文件),

其中,字节码文件的文件名就是每一个类的类名。须要注意的是,类即便不在源文件中定义,但被源文件引用,

编译后,也会编程相应的字节码文件,如类A引用类C,但类C不定义在类A的源文件中,编译后,类C也被编

译成对应的字节码文件C.class

三 执行java源文件


 执行java源文件,用java.exe执行便可

到如今,java源程序基本执行结果,并正确打印咱们指望的结果,那么,如上的步骤,咱们能够总结以下:

如上总结,已经抽象化了在JVM中的执行,接下来,咱们将分析,字节码文件(.calss文件)如何在虚拟机中一步一执行的。

四 JVM如何执行字节码文件


 (一) 装载字节码文件

        当.java源码被javac.exe编译器编译成.class字节码文件后,接下来的工做就交给JVM处理,JVM首先经过类加载器(ClassLoader)

将class文件和相关Java API加载装入JVM,以供JVM后续处理。

       在该阶段中,涉及到以下一些基本概念和知识。

 1.JDK,JRE和JVM关系

(1)JDK(Java Development Kit),Java开发工具包,主要用于开发,在JDK7前,JDK包括JRE

(2)JRE(Java Runtime Environment),Java程序运行的核心环境,包括JVM和一些核心库

(3)JVM(Java Virtual Machine),VM是一种用于计算设备的规范,它是一个虚构出来的计算机,是经过在实际的计算机上仿真模拟

         各类计算机功能来实现的,是JRE核心模块。

2.JVM

       JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是经过在实际的计算机上仿真模拟各类计算机功能来实现的。Java虚拟机

虚拟机的主要任务是装载class文件并执行其中的字节码,不一样的Java虚拟机中,执行引擎可能由不一样的实现,大体有以下几种引擎:

  •    一次性解释字节码引擎
  •     即时编译引擎
  •    自适应优化器

     关于虚拟机的实现方式,采用软件方式、硬件方式和软件硬件结合方式,这个要根据具体厂商而定。

3.什么是ClassLoader

       虚拟机的主要任务是装载class文件并执行其中的字节码,而class文件是由虚拟机的类加载器(ClassLoader)完成的,在一个Java虚拟机,

有可能存在多个类加载器。

       任何java运用程序,可能会使用两种类加载器,即启动类加载器(bootstrap)和用户自定义类加载器。

       启动类加载器是Java虚拟机惟一实现的一部分,它又可分为原始类装载器,系统类装载器或默认类装载器,它的主要做用是从操做系统的

磁盘装载相应的类,如Java API类等。

       用户自定义装载类,按照用户自定义的方式来装载类。

(二)将字节码文件存储在JVM内存区

       当JAVA虚拟机运行一个程序时,它须要内存来存储许多东西,如字节码,从已装载的class文件中获得的其余信息,程序建立的对象,传递给

方法的参数,返回值,局部变量以及运算的中间结果等,这些相关信息被组织到“运行时数据区”。

       根据厂商的不一样,在Java虚拟机中,运行时数据区也有所不一样,有些运行时数据区由线程共享,有些只能由某个特定线程共享。运行时数据区

大体可分几个区:方法区,堆区,栈区,PC寄存器区和本地方法栈区。

       在该阶段中,涉及到以下基本概念和知识。

      1.方法区

        方法区用来存储解析被加载的class文件的相关信息。当虚拟装载一个class文件后,它会从这个class文件包含的二进制数据中解析类型信息,而后将

该相关信息存储到方法区中。

      2.堆

         堆是用来存储相关引用类型的,如new对象。当程序运行时,虚拟机会把全部该程序在运行时建立的对象都放到堆中。

     3.PC寄存器

        PC寄存器主要用来存储线程。当新建立一个线程时,该线程都将获得一个本身的PC寄存器(程序计数器)以及一个java栈。

Java虚拟机没有寄存器,其指令集使用Java栈来存储中间数据。

     4.栈区

       栈区主要用来存储值类型的,如基本数据类型,须要注意的时,String为引用类型,是存在堆中的。Java栈是由许多栈

帧组成的,一个栈帧包含一个Java方法调用的状态,当线程调用一个方法时,虚拟机压入一个新的栈帧到该线程的Java栈中

,当该方法返回时,这个栈帧从Java栈中弹出。

(三)执行引擎与运行时数据区交互

   运行时数据区为执行引擎提供了执行环境和相关数据,执行引擎经过与运行时数据区交互,从而获取

执行时须要的相关信息,存储执行的中间结果等

 

(四)执行引擎与本地方法接口

当要执行本地方法时,执行引擎将调用本地方法接口来获取相关OS本地方法,须要注意的是,本地方法与操做系统强耦合的。

(五)JVM在具体操做系统上执行

JVM经过调用本地接口来获取本地方法,从而实如今具体的平台上执行,如在Linux系统上执行,在Window系统上

执行和在Unix系统上执行。

五  参考文献


 【01】深刻Java虚拟机(原书第2版)(美)Bill Venners 著  

【02】Core Java Volume I - Fundamententals(10th Edition) (美) Cay S.Horstmann

【03】Core Java Volume I - Advanced Features(10th Edition) (美) Cay S.Horstmann

六  版权区


  •    转载博客,必须注明博客出处
  •    博主网址:http://www.cnblogs.com/wangjiming/
  •    如您有新想法,欢迎提出,邮箱:2098469527@qq.com
  •   专业.NET之家技术QQ群:490539956
  •   专业化Java之家QQ群:924412846
  •   有问必答QQ群:2098469527
  •   一对一技术辅导QQ:2098469527
相关文章
相关标签/搜索