《Java 底层原理》Jvm 类的加载原理
2021-03-05 20:29
标签:st3 语言 src puts 提升 内存 出现 war string 一直想好好的了解一下JVM,这次就来一起了解一下JVM是如何实现类的加载过程的。 类加载的生命周期 1. 加载 5种类加载情况: 因为Java类加载是不关心这个文件来自哪里? 所有Java的对象可以来自Jar,war,网络,CGlib,数据库等等。 使用到对象才会加载。 2. 验证 3. 准备 为静态变量分配内存、为基础数据类型赋初值, 如果被final修饰,在编译的时候会给属性添加ConstantValue属性,准备阶段直接完成赋值操作,无需赋初值。 4. 解析 间接引用转直接引用。 间接引用:指向常量池。 直接引用:指向内存地址。 5. 初始化 执行静态代码段(静态代码块,静态变量):clinit 测试代码写了一个静态变量b 通过字节码文件也能清楚的看到信息。 静态代码的执行顺序和定义的顺序一致,改点可以通过案例说明。 运行结果: 运行结果是1和1 ,造成这个结果的原因就是静态代码的顺序执行,先创建了对象,对象中构造函数执行了, 后面再执行 public static int val2 = 1 ,值就被覆盖回去了。 6. 使用 对象已经初始化完成,这个对象就可以再其他地方被使用。 7. 卸载 销毁之前加载的对象信息。 Jvm里面有一个类状态的枚举: 1. jvm类加载会加锁,防止类加载出现资源争用的情况。 通过一个案例证明一下: 运行结果: 执行被锁,无法继续执行。 2. Jvm加载对象属于懒加载(对象没有使用的时候,不会去加载该对象),下面通过案例说明: 运行结果: 可以明显的看到B的static方法没有被执行,因为这段逻辑中,不需要是到B这个对象,哪怕B对象是A对象的子类。 Jvm 类加载是核心逻辑之一,非常重要,对一个变成人员的提升也是非常的有帮助。 《Java 底层原理》Jvm 类的加载原理 标签:st3 语言 src puts 提升 内存 出现 war string 原文地址:https://www.cnblogs.com/jssj/p/14259220.html前言
原理
public class JvmTest1 {
public static void main(String[] args) {
Test1 test1 = Test1.getTest();
System.out.println(Test1.val1);
System.out.println(Test1.val2);
}
}
class Test1{
public static int val1 ;
Test1(){
val1++;
val2++;
}
public static Test1 instance = new Test1();
public static int val2 = 1 ; // 该代码放在在初始化代码
public static Test1 getTest(){
return instance;
}
}
JVM类加载细节
public class JvmTest3 {
public static void main(String[] args) {
new Thread(() -> {
while(true){
new AA();
}
}).start();
new Thread(() -> {
while(true) {
new BB();
}
}).start();
}
}
class AA{
static {
System.out.println("创建AA对象");
new BB();
}
}
class BB{
static {
System.out.println("创建BB对象");
new AA();
}
}
public class JvmTest2 {
public static void main(String[] args) {
System.out.println(B.str);
}
}
class A {
static String str = "a";
static {
System.out.println("static a");
}
}
class B extends A {
static {
System.out.println("static b");
}
}
总结
文章标题:《Java 底层原理》Jvm 类的加载原理
文章链接:http://soscw.com/index.php/essay/60606.html