当虚拟机遇到new指令,会创建一个对象。
1. 类加载检测:
检查该指令的参数是否在常量池中定位到一个类的引用,检查该引用代表的类是否已经被加载、解析、初始化过。如果没有,就先执行类加载过程。
Student student=new Student(user); 先去看user代表的类加载没有,在去执行new指令。
2. 给新生成的对象(实例)分配内存:
该实例所需的内存大小在类加载的时候就已经确定。如果是规整的堆,只需要把指针挪动下就行。而不规整的JVM需要维护一个列表。规整不规整要看gc有没有压缩整理功能。
可能出现的问题:
分配内存时候可能出现线程安全的问题。正给A实例分配内存,指针还没修改,B实例又使用了该内存空间。
解决方案:
使用每个线程私有的线程缓冲区(TLAB),该缓冲区是一开始就分配好的,线程自己单独使用,不会造成冲突。只有当TLAB耗尽,才进行同步锁定。开启TLAB:-XX:+/-UseTLAB.
3. 清空内存空间
将所有内存空间都初始化为零。体现在Java代码中对象的实例字段不用赋值就可以直接拿来使用。
4. 设置对象头
该对象属于哪个类的实例、如何找到类的元数据信息、对象的Hash码、GC分代年龄、是否使用偏向锁。
又叫Mark Word.
5. 执行init方法
以上操作字段都是空,需要按照代码设置来赋值。