生命不息,学习不止,对一切都要维持敬畏之心。
若有不正之处,请谅解和批评指正,不胜感激。
1.类加载
1.1 时机
- new关键字
- 读取或设置static字段
- 调用static方法
- 反射
- 初始化类过程中发现其父类没有被初始化
- 1.8版本接口中的default方法,其实现类初始化之前,要初始化接口类
1.2 过程
- 加载:二进制流读入内存
- 验证:确保字节流中的信息符合<JAVA虚拟机规范>
- 准备:静态变量,分配内存,初始化
- 解析:虚拟机常量池中符号引用替换为直接引用
- 初始化:根据代码指定的主观计划,去初始化资源(如变量)
1.3 类加载器
- java.lang.ClassLoader是所有类加载器的父类
- 引导类加载器Bootstrap
- 扩展类加载器ExtClassLoader
- 应用类加载器AppClassLoader
- 双亲委派机制:当AppClassLoader收到一个加载类的请求时,会先让他的父类加载器ExtClassLoader尝试加载,ExtClassLoader也会让他的父类加载器Bootstrap尝试加载,如果Bootstrap能加载,就加载该类。如果Bootstrap不能加载,则ExtClassLoader会进行加载,如果也不能加载,AppClassLoader会进行加载。这样可以很好的避免核心类被篡改,保证了java运行的稳定性.
- 当一个类的class文件被类加载器加载到内存后,类的加载器会创建出此class文件的对象。class文件的对象是Class类的对象
2.对象的创建流程
- 虚拟机遇到new指令时,检查这个对应的类能否在常量池中定位到一个类的符号引用
- 判断这个是否已被加载,验证,准备,解析和初始化
- 在堆中为对象分配空间
- 指针碰撞:堆的内存分配规律,一边占用另一边空闲,中间为指针,挪动对象大小的空间赋予对象.
- 空闲列表:堆的内存分配不规律,已被使用的内存和空闲内存交错,虚拟机维护一个列表
- 按照垃圾回收算法决定使用哪一种对象分配空间
- 指针碰撞效率较高
- 初始化内存空间为零
- 设置对象头信息
- Mark Word(hash值,锁信息等)和类型指针(指向类)
- 实例数据(字段等)
- 对齐填充(8的倍数)
- 执行init方法
3.对象定位
句柄访问
指针访问
对比
- 垃圾回收:句柄访问不需要更改对象地址,指针访问需要
- 访问效率:HoSpot采用指针访问,访问高校,不需要到句柄池拿取指针