码迷,mamicode.com
首页 > 编程语言 > 详细

Java Class Loader

时间:2020-01-14 09:42:11      阅读:73      评论:0      收藏:0      [点我收藏+]

标签:链接   目的   文件中   动态   抽象方法   分代   要求   com   转换   

1.结束一个JVM生命周期的方式:
System.exit()
Normal finish done
encounter the error or exception
crash,出core
操作系统问题或者硬件导致

2.类加载的三个阶段:
加载:查找并且加载类的二进制数据
链接:--验证:确保被加载类的正确性
--准备:为类的静态变量分配内存,并将其初始化为默认值
--解析:把类的符号引用转换为直接引用
初始化:为类的静态变量赋予正确的初始值

技术图片

3.所有的java虚拟机实现必须在每个类或者接口被java程序首次主动使用时才初始化他们,当然现代JVM有可能根据程序上下文语义推断出接下来可能初始化谁

4.类的主动使用和被动使用
主动使用:
--new,直接使用
--访问某个类或接口的静态变量,或者对该静态变量进行赋值操作
a.对某个类的静态变量进行读写->class
b.对接口中静态变量进行读取->interface
--调用静态方法
--反射某个类
--初始化一个子类
--启动类,比如java HelloWorld
除了上述六个以外,其余的都是被动使用,不会导致类的初始化

注意:(1)通过子类访问父类的static变量,不会导致子类的初始化
   (2)定义引用数组,不会初始化类
   (3)final修饰的常量会在编译期间放到常量池中,不会初始化类
   (4)final修饰的复杂类型,在编译期间无法计算得出,会初始化类

5.类加载阶段详解:
类的加载简单来说,就是将class文件的二进制数据读取到内存,将其放到方法区中,然后在堆区中创建一个java.lang.Class对象,
用来封装在方法区的数据结构

技术图片

 

 

 

6.1类加载的最终产品是位于堆区中class对象
6.2加载类的方式
本地磁盘中直接加载
内存中直接加载
通过网络加载.class
从zip,jar等归档文件中加载.class文件
数据库中提取.class文件
动态编译

技术图片

7.链接阶段
在加载阶段完成后,虚拟机外部的二进制数据量就会按照虚拟机所需的格式存储在方法区中(数据结构),然后在堆区中创建一个class对象,这个对象
作为程序访问方法区中这些数据的外部接口。
加载阶段与链接阶段的部分内容是可以交叉进行的,比如一部分代码加载完成就可以进行验证,提高效率。
7.1
验证的主要目的是确保class文件中的字节流中包含的信息符合虚拟机的要求,并且不会损害到JVM自身的安全
VerifyError
文件格式验证:
(1)魔术因子是否正确,OxCAFEBABE
(2)主从版本号是否符合当前虚拟机
(3)常量池中的常量类型是不是不支持
(4)etc
元数据验证:
(1)是否有父类
(2)父类是不是允许继承
(3)是否实现了抽象方法
(4)是否覆盖了父类的final字段
(5)其他的语义检查
字节码验证:
主要进行数据流和控制流的分析,不会出现这样的情况,在操作栈中放置了一个int类型,但是却给了一个long型的数据
符号引用验证:
调用了一个不存在方法,字段等等
符号引用验证的目的是确保解析动作能正常进行,如果无法通过符号引用验证,将会抛出一个 java.lang.IncompatibleClassChangeError异常的子类,如
java.lang.IllegalAccessError、java.lang.NoSuchFieldError、java.lang.NoSuchMethodError等

8.准备阶段
准备阶段就是给类变量分配初始值

Java Class Loader

标签:链接   目的   文件中   动态   抽象方法   分代   要求   com   转换   

原文地址:https://www.cnblogs.com/zheaven/p/12190256.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!