Java对象创建

        创建一个Java只要使用new关键字就可以,但是在我们new一个对象的时候,虚拟机中经历的过程要比调用new关键字这一行代码复杂的多。

        虚拟机遇到一个new指令时,先去常量池中检查这个类是否被加载解析和初始化,如果没有,则会先执行类加载过程。

        当类加载检查通过后,虚拟机会为新生对象分配内存空间。新生对象所需的内存大小在类加载完成后便可完全确定,为对象分配空间的任务就是把一块确定大小的内存从java堆中划分出来。如果java堆的内存是规整的,已使用的内存放一边,空闲的内存放领一边,中间用一个指针作为分隔,内存分配只要把这个指针移动与新生对象大小相等的距离即可(指针碰撞)。如果内存不是规整的,虚拟机要维护一个列表,记录哪些内存块是可用的,分配的时候从列表中找出一块足够大的空间分配给新生对象,并更新记录(空闲列表)。

        对象的创建在虚拟机中是非常频繁的,即时仅仅修改一个指针的位置,在多线程并发下也不是安全的。解决这个问题有两种方法,一种是对内存空间的动作进行同步处理。另一种是把内存分配的动作按照线程划分在不同的空间中进行,内个线程在java堆中预先分配一小块内存,成为本地线程分配缓冲区(TLAB),只有一个线程的TLAB用完了申请新的TLAB时才需要同步锁定。

        内存分配完成后,虚拟机会将分配到的内存空间都初始化为零值。Java中一个对象的成员变量声明了没有实例化,基本数据类型都为0或false等初始值,对象因为指针找不到对象会为null。之后虚拟机会对对象进行必要的设置,因为当前只是在内存空间申请了一块内存空间,还有设置这个对象是哪个类的实例,对象的哈希码,对象的GC分代年龄等信息。这些信息存放在对象的对象头中。然后会调用新对象的<init>方法,此时一个对象才算真正的创建完成。(new关键字执行完毕)

        对象在内存中存储分为3部分,对象头,实例数据和对齐填充。头包含两部分,第一部分存储对象自身的运行时数据,如哈希码,GC年龄,锁状态标志等信息,这部分数据的长度在32位和64位虚拟机中的大小分别是322bit和64bit。另一部分是类型指针,既标识这个对象是哪个类的实例。实例部分就是对象真正存储的有效信息。第三部分对齐填充不是必须存在的,仅仅起占位符的作用,因为Java对象的起始地址必须是8字节的整数倍,也就是说对象的大小必须是8字节的整数倍,当实例数据没有对齐时,要靠对齐填充来补全。

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值