对象创建、类加载等问题是java中比较难以理解的底层知识点,涉及到的知识一般小厂平时中不常用到,但也是面试必问的知识点,所以通过代码+图文的方式来梳理一下这块的知识点,抛砖引玉
package jvm;
public class NewObject {
public static void main(String[] args) {
Object o = new Object();
synchronized (o) {
System.out.println(o.hashCode());
}
}
}
创建对象
Object o = new Object();
这句代码对应的字节码指令如下
0 new #2 <java/lang/Object> //开辟一块内存空间
3 dup //复制文件描述符
4 invokespecial #1 <java/lang/Object.<init> : ()V> //启动对象的构造函数init方法
7 astore_1 //将Object类的引用存入main方法的局部变量表中,供调用方调用变量
8 return //main方法结束运行
这里会出现DCL(double check lock)问题,原因在于 开辟内存空间(new )、调用构造方法(invokespecial )、指针指向(astore_1 ) 三条语句的执行顺序可能被CPU进行指令重排序,导致new->astore->invoke的顺序执行,如果此刻有一个线程判断对象!=null 就拿走使用,此刻的对象并未执行构造方法,就会导致一些问题。