类的加载过程: 加载,验证,准备,解析,初始化
1加载: 类加载指的是将类的class文件读入内存,并为之创建一个java.lang.class对象.
类的加载由类加载器完成, 类加载器通常由jvm提供, 这些类加载器是所有程序运行的基础, jvm提供的,通常称为系统类加载器,
开发者可以通过集成classloader基类来创建自定义的类加载器
通过使用不同的类加载器,可以从不同来源加载类的二进制数据,通常有以下来源:
当加载完,系统生成对应的class对象,就会进入连接状态,该链接负责将类的二进制数据合并到 jre 中
- 从本地磁盘加载class文件,这是大部分程序的来源.
- 从jar包加载class文件,这种方式也比较常见,比如mysql驱动类,ssm核心包
- 通过网络加载class文件
- 把一个源文件动态编译,并执行加载
2.验证: 检测class文件的版本是否可以兼容当前jvm版本 , class文件是否已满足jvm规范
3.准备: 将类成员初始化为初始值,final的类变量除外.final变量直接初始化为所赋的值
4.解析: 将符号引用解析为直接引用,将变量变为直接引用内存地址
5.初始化: 主要对类变量进行初始化.
在java中,初始化类变量有俩种方式:(顺序执行)
- 声明类变量时指定初始值
- 使用静态初始化块为类变量指定初始值
jvm初始化一个类包含以下步骤:
1.假如这个类还没有被加载和连接,则程序先加载并连接该类
2.假如该类的直接父类还没有被初始化,则先初始化父类
3.假如类中有初始化语句,则系统依次执行这些初始化语句
当执行第二步的时候,系统对直接父类的初始化步骤也遵循此步骤1~3;如果该父类又有直接父类,则系统再次重复这三个步骤来先初始化这个父类........依次类推,所以jvm最先初始化的总是java.lang.Object类
当程序主动使用任何一个类时,系统会保证该类以及所有父类(包括直接父类和间接父类)都会被初始化 .这就是著名的双亲委派机制
java中对象创建过程: Hello hello = new Hello();
当执行碰到 new 关键字时.那么main主线程便在自己的
1.线程栈中声明一个对象Hello hello;
2.在jvm的堆空间中申请一片内存地址,然后将Hello相关信息如:实例变量,实例方法等从方法去加载到堆内存中
3.在堆内存中创建对象的时候执行顺序:
a,加载实例信息进入开辟的内存中
b.执行构造方法,就是<init>方法
对象头部信息:
1.对其填充
2.持有指向方法区的指针
3.描述信息(持有当前对象锁的线程的id和持有对象锁线程的个数 , 在gc中存活的生命周期数 , 偏向锁的标志)
偏向锁:当前线程已经对此对象上锁后 , 执行完毕 如果下次访问该对象的线程还是上一次的线程,那么不对此对象重新上锁.