java运行时数据区域-----对象的创建

对象的创建:虚拟机遇到一个new关键字时,先会去常量池中检查是否有这个类的符号引用,并检查这个类所代表的类是否已经被加载,解析,初始化如果没有,那就必须先进行相应的类加载过程。在类加载过程通过后,接下来将为新生的对象分配内存(从java堆中划分出来一片内存区域出来)。

1如果java堆中的内存是规整的左边我们叫做A区域,存放已经使用过的内存,右边我们叫B区域,存放着还没使用的内存区域,中间放着指示器,只需要将指示器向右边挪动一小段,这种方式我们称作指针碰撞。

2如果java堆中内训区域是分散的,那就不能进行简单的指针碰撞,虚拟机必须维护一个列表,记录那些内存块是可用的,在分配的时候找到足够大的一块分配给对象实例,并更新列表上的记录,这种分配方式成做空闲列表。

选择以上那种方式由java堆是否规整决定,而java堆是否规整又由所采用的垃圾收集器是否带有压缩整理功能决定。

对象的创建在jvm中是一个非常频繁的过程,有可能正在给对象A分配内存,指针好美来的及进行修改,对象B又同时使用了原来的指针进行分配内存,这样子是非常不安全的,解决这种问题有两个方案。

1是对分配内存的动作进行同步处理---采用CAS配上失败重试来保证更新操作的原子性。

2将内存分配的动作按照线程划分在不同的空间中进行,即每个线程在java堆中预先分配一小块内存,成为本地线程分配缓冲。

内存分配完成时,虚拟机需要将分配到的空间都初始化为0,接下来需要对创建的对象进行一定的标识,例如这个对象是那个类的实例,如何才能找到类的元数据信息,对象的哈希码,对象的GC分代年龄等等,这些信息存放在java对象投之中。

在上面的工作都完成之后,从虚拟机的角度来看,一个新的对象已将产生了,但是从java程序的角度来看,对象的创建才刚刚开始,<init>方法还没有执行,多有的字段还为0,执行new指令之后,然后会紧接着执行init方法,

猜你喜欢

转载自blog.csdn.net/lsm18829224913/article/details/80243237