运行过程
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.哪里破坏了双亲委派机制
来源:oschina
链接:https://my.oschina.net/u/4263748/blog/4179862