jvm学习笔记:一、类的加载、连接、初始化
- 在JAVA代码中,类型的加载、连接与初始化过程都是程序运行期间完成的。
- 类型的加载:将已经存在的class从硬盘加载到内存。
- 类型的连接:将类与类之间的关系确定好。
- 类型的初始化:类型 静态的变量进行赋值。
- 类加载器(classLoader)的深入剖析
- 每一个类都是由类加载器加载到类型当中
- 在以下代码中,java虚拟机会结束生命周期:
- 执行System.exit()方法。
- 程序正常结束。
- 程序在执行中遇到异常或者错误而异常终止。(没有去捕获异常,一直抛到main方法) - 由于操作系统出现错误,导致JAVA虚拟机进程终止。
- 加载、连接、初始化
- 加载:查找并加载类的二进制数据
- 连接:
- 验证:确保被加载类的正确性。
- 准备:为类的静态变量分配内存,并将其初始化为默认值。
例1:pulic static int a = 1; 会将0作为默认值赋值给a,而不是1. - 解析:把类中的符号(间接)引用转化为直接引用(通过指针)。
- 初始化:为类的静态变量赋予正确的初始值。
例2: 将例1中的a 赋值正确的初始值1;
- java程序对类对使用方式分为两种。
- 主动使用
- 被动使用
-
所有java虚拟机实现必须在每个类或接口被java程序“首次主动使用”时才会加载他们。
-
主动使用(七种)
- 创建类对实例 new User();
- 访问某个类或者接口对静态变量(getstatic),或者对静态变量赋值(putstatic)
- 调用类对静态方法 (invokestatic)
- 反射 (Class.forName("com.chen.Test"))
- 初始化一个类对子类 (初始化类 child类,也是对parent类进行初始化 child extend parent)
- JDK1.7 提供动态语言的支持(java.lang.invoke.MethodHandle实例的解析结果REF_getStatic,REF_putStatic,REF_invokeStatic句柄对应的类没有初始化,则初始化)
- 被动使用:
- 除了其他七种情况外,其他使用java类的方式都被看做类的被动使用,都不会导致类的初始化(但可以被加载和连接)
- 类的加载
- 类的加载指 类的CLass的二进制数据读入到内存当中,将其放在运行时数据区的方法区内,然后在内存中创建一个java.lang.Class对象(规范并未说明Class对象在哪里,HotSpot虚拟机将其放在方法区内)用来封装类在方法区内的数据结构。
- 类的加载方式
- 从本地系统中直接加载
- 通过网络下载.class文件加载
- 从jar zip 等归档中加载.class文件
- 从专有数据库中提取.class
- 将java源文件动态编译为.class文件