java运行机制

落爺英雄遲暮 提交于 2021-02-02 13:53:23

运行过程


1.编写源文件(.java)

2.java源文件由编译器(javac.exe)编译为字节码文件(.class)

3.打包为jar或war

4.启动程序(启动程序后)

源代码->机器码过程解析


  java源代码需要先由编译器编译为字节码文件,然后字节码文件再有java虚拟机(jvm)解释为机器码,才能被机器识别。jvm分为linux版本和windows版本,分别运行在linux和windows的服务器上。正是由于中间物字节码文件的存在,才使得java具有可移植性,一次编译,到处运行。

jvm介绍


一、jvm概念

  jvm是Java Virtual Machine(java虚拟机)的缩写。JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。

二、jvm启动过程和生命周期

  1.启动程序第一步就是启动jvm,jvm启动后会进行jvm的初始化,最后操作class文件,找到main方法执行。具体步骤如图:

  2.java源代码-》编译为class文件-》加载jvm.cfg配置文件-》加载jvm.dll文件-》初始化jvm-》获取JNI接口-》类加载器加载class文件-》找到main文件执行

三、jvm生命周期

  当启动一个java程序时,生成一个jvm实例;程序关闭,实例销毁。

四、jvm的内部体系结构分为三部分

    1)类加载器(ClassLoader)子系统

    2)执行引擎

    3)运行时数据区

jvm类加载器工作原理


一、类加载器作用:将对应类的.class文件中的二进制流加载到内存空间

二、加载过程:

      

1.加载:主要完成三件事情:

   1>通过类的全限定名获取定义此类的二进制字节流 

   2>将这个类字节流代表的静态存储结构转为方法区的运行时数据结构

   3>在中生成一个代表此类的java.lang.Class对象,作为访问方法区这些数据结构的入口

2.验证:检验class文件是否符合jvm规范,是否会影响jvm使用的安全性。

3.准备:为类变量(static静态变量)分配内存,并设置初始值。

  注:1>仅为类变量(static静态变量)在方法区分配内存,不包括非静态变量和方法

    2>设置初始值,一般情况下是设置为o或者null;特殊情况时,用static final修饰的变量,设置初始值为程序中指定的值。

      假如  public static int a=8;   设置初始值为a=0,而不是a=8

          public static final int a=8;  设置初始值为a=8

4.解析:虚拟机常量池内的符号引用替换为直接引用(地址引用)的过程。

5.初始化:类加载的最后一步,会将类的方法和变量进行初始化。

  1>以下四种情况会进行初始化:

     遇到new、getstatic、putstatic、invokestatic这四条字节码指令时,如果类还没有进行过初始化,则需要先触发其初始化。

    使用Java.lang.refect包的方法对类进行反射调用时,如果类还没有进行过初始化,则需要先触发其初始化。

    当初始化一个类的时候,如果发现其父类还没有进行初始化,则需要先触发其父类的初始化。

    当虚拟机启动时,用户需要指定一个要执行的主类,虚拟机会先执行该主类。

  2>初始化顺序:

       

双亲委派机制  


一、模型图      

启动类加载器(Bootstrap ClassLoader):加载JDK的/lib目录下的类

扩展类加载器(Extension ClassLoader):加载JDK的/lib/ext目录下的类

应用程序类加载器(Application ClassLoader):程序自己classpath下的类

自定义类加载器(ClassLoader):程序人员指定的特殊目录

 

二、定义

  双亲委派模式指的是类加载器要加载一个类,首先会委派给父类加载器加载,一层层向上传递,直到最顶层加载器即启动类加载器。如果父类加载器不能加载,则返回异常给子类加载器,由子类加载器加载。注意,这里的父类不是指的继承关系,只是程序调用中逻辑父子关系。

三、原理

  双亲委派机制的优点是不会重复加载相同名称的类到内存中,例如java.lang.Object类最终都会从启动类加载器加载,即使用户自己定义了一个相同的类,最终jvm也只会加载<JAVA_HOME>\lib中rt.jar里面的java.lang.Object类。使得系统可以稳定运行,不至于由于出现多个object类而迷乱。

四、破坏双亲委派机制

  1.为什么破坏双亲委派机制

  根据类加载机制,当被装载的类引用了另外一个类的时候,虚拟机就会使用装载第一个类的类装载器(父类装载器)装载被引用的类。当装载的类引用了一另一个类,而这个类在父类装载器中不存在需要去子类装载器装载时,双亲委派机制就会出现问题。例如:JDBC的Driver接口定义在JDK中,其实现由各个数据库的服务商来提供,比如MySQL驱动包。DriverManager 类中要加载各个实现了Driver接口的类,然后进行管理,但是DriverManager位于 JAVA_HOME中jre/lib/rt.jar 包,由BootStrap类加载器加载,而其Driver接口的实现类是位于服务商提供的 Jar 包。根据类加载机制,DriverManager已经由BootStrap类加载器加载,不能再去子类加载器去加载实现了Driver接口的类。

  2.哪里破坏了双亲委派机制

  

  

  

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!