JVM产生以及引用一个对象
JVM如何产生一个对象?
程序员视角:new clone 反序列化 都可以生成一个对象在内存中。(JVM的给我们带来的方便,两个字:伟大)
JVM视角:(大约需要以下5步骤)
1. (验证类加载)检查创建对象的指令参数,能否在常量池中定位到一个类符号的引用(Class信息存放在方法区中,常量池也是方法区的一部分)。并且检查这个符号引用代表的类是否已经被加载,初始化。
2.(为新生对象分配内存)由于一个对象所需内存在类加载完成后便可以确定了(一个对象分为对象头(32位机器32bit、64位机器64bit),实例数据(类中定义的各种类型的字段,包括从父类中继承下来的),对其填充(占位作用,JVM规定对象大小必须是8字节的整数倍)),因此给对象划分内存等同于从堆中直接划分一段内存出来。分配方式:指针碰撞和空闲列表两种方法。
2.1在分配内存时,需要考虑线程安全。两个解决方案:a)采用 CAS配上失败重试,保证原子性。
b) 将内存按照线程划分到不同的空间去进行分配,称为本地线程分配缓冲(Thread Local Allocation Buffer)
3.(将分配到的内存空间初始化为零)不包括对象头。 如果采用TLAB方式,可以提前至TLAB分配时进行这步。
4.(对新生对象的头信息进行补充,例如对象是哪个类的,hashCode,GC分代年龄等)
5.(执行初始化方法,这个初始化方法是按照程序员的意愿去处理这个对象的初始化工作)执行构造方法的赋值代码等。
JVM如何引用一个对象?(图片来自JVM高级特性第二版)
1.句柄
2.直接指针
这样两种访问方式的优缺点很明确了:
有句柄池的速度慢,没有句柄池的怕对象的移动。