一. 通过javac命令*.java文件编译为*.class字节码文件
二. 通过类加载子系统加载字节码文件,类的加载过程如下
-
加载环节:
a. 通过一个类的全限定名获取定义此类的二进制字节流
b. 将这个字节流所代表的静态存储结构转化为方法区的运行时的结构
c. 在内存中生成一个代表这个类的class对象,作为方法区这个类的各种数据的访问入口 -
链接环节
a. 验证(verity):确保class文件包含的信息符合虚拟机的要求(比如检查class文件是否是以cafe babe开头),保证被加载的类的正确性,以及保证虚拟机的安全;主要包括四种验证:文件格式验证、元数据验证、字节码验证、符号引用验证。b. 准备(prepare):为类变量分配内存并且设置类变量的默认初始值(例如int的默认值为0)。注意点:不包含被final修饰的static,因为final在编译的时候就被分配了内存,在该阶段时,初始化值会直接赋值(不是赋默认值)。实例变量(也就是在方法中定义的对象,比如:Student stu = new Student)不会被分配内存和初始化,类变量会分配在方法区中,而实例变量会被分配到堆中。
c. 解析(resolve):将常量池内的符号引用转为直接引用的过程;事实上,解析操作往往会伴随着jvm在执行完初始化之后再执行。符号引用:用一组符号来描述所引用的目标。直接引用:直接指向目标的指针、相对偏移量或一个间接定位到目标的句柄(理解为编号)。解析动作主要针对类或接口、字段、类方法、接口方法、方法类型等;对应常量池的CONSTANT_CLASS_INFO、CONSTANT_Fieldref_INFO、CONSTANT_Methodref_INFO。
-
初始化环节
a. 初始化过程就是执行类构造方法<clinit>()的过程,此方法不需要定义,它是javac编译器自动收集类中的所有类变量的赋值动作和静态代码块中语句合并而来。<clinit>()的执行指令顺序按在源文件的出现的顺序执行
b. 测试执行
c. 如果该类具有父类,JVM会保证子类的<clinit>()执行前,父类的<clinit>()已经执行完毕。d. jvm必须保证一个类的<clinit>()方法在多线程下是被同步加锁的
e. 如果类中没有定义静态变量和静态代码块,那么在jvm中不会生成<clinit>()方法
f. <clinit>()方法展示:
三. 类加载器的分类
-
引导类加载器(bootstrap ClassLoader)
a. 由c/c++实现,嵌套在jvm内部
b. 用来加载java的核心类库JAVA_HOME/jre/lib/rt.jar、resources.jar、sun.boot.class.path路径下的类,用于提供JVM自身需要的类
c. 不是继承ClassLoader,没有父加载器
d. 加载扩展类(ExtensionClassLoader)和程序类(AppClassLoader)加载器,并指定为他们的父加载器
e. 出于安全考虑,启动类加载器只加载包名为:java、javax、sun等开头的类
f. 获取bootstrapClassLoader能加载的api路径
-
自定义类加载器(User-Definde ClassLoader)
a. 所有派生于抽象类ClassLoader的类加载器都划分为自定义类加载器(包含ExtensionClassLoader和AppClassLoader)
b. 我们用户有时候要自己定义一个类加载器,基于以下原因:
i. 为了隔离加载类
ii. 修改类加载的方式
iii. 扩展加载源
iv. 防止源码泄露b. 扩展类加载器(ExtensionClassLoader)
i. 用来加载java的核心类库JAVA_HOME/jre/lib/ext下的类,如果用户创建的jar放在此目录下,也会自动由扩展类加载器去加载。
ii. 获取扩展类加载器能加载的类的路径
c. 系统类加载器(AppClassLoader)
i. 父类加载器为扩展类加载器。
ii. 负责加载环境变量classpath或者java.class.path指定路径下的类库。
iii. 该类是程序中的默认类加载器,一般来说,java应用的类都由该加载器完成加载
iv. 通过ClassLoader.getSystemClassLoader()可以获取到该类加载器 -
测试
四. 双亲委派模型
-
过程
在java中,jvm加载类都是按需加载,需要用到该类时,才会进行加载;在加载类的时候,无论是加载我们平时定义的普通类,还是加载jdk类库中的类,都会先尝试从引导类加载器(bootstrap ClassLoader)加载,如果加载成功,则直接采用该加载类进行加载,否则再尝试从扩展类加载器(ExtensionClassLoader)进行加载,如果加载成功,则直接采用该加载类进行加载,否则直接采用系统类加载器(AppClassLoader)进行加载。 -
原因分析
保证自定义的类不能与jdk核心类库的全路径一样,保证虚拟机的安全和程序的不混乱。
四. 沙箱机制
-
什么是沙箱机制?
限制应用程序对系统资源的访问的运行环境,保护系统不被破坏和恶意攻击 -
体现
后续继续更新