java对象的创建
创建一个对象的方式:
1)new
2) 反射
3)clone方法
4)反序列化
1)和2)都是通过的 Class对象来创建的对象实例,那么 clone方法和反序列化有用到Class对象吗?
先深入探究一个 new这个关键字!
1)执行new时,先去检查这个类是否已经加载
2) 为对象在内存中分配内存 ,(类加载完成后,就能够确定对象占用的内存大小)
(分配内存实质就是就内存中的一块区域从堆中划分出来,用来防止该对象实例)
内存大小确定了 ,那么如何分配内存?
分配内存分为:指针碰撞 和 空闲列表 (具体采用哪种方式与 回收算法有关系)
指针碰撞:每次向空闲方向移动对象占用内存的大小。 (这种要求内存是规整的,使用了的内存在一边,未使用的内存在一边,中间是一个指针)
空闲列表:如果内存不是规整的(比如采用了标记清除算法),那么就需要维护一个空闲列表,用来记录哪些内存块是可用的。
所以,当使用 Serial ParNew这些垃圾回收器时,系统采用的是指针碰撞,用CMS时,采用的是空闲列表。
而且!!! JVM考虑到了并发的情况!!( 防止给一个对象分配内存,指针还没有修改,另一个对象又来分配内存) 采用了两种方式:
1) 采用CAS 来进行对象的内存分配
2)每个线程在Java堆中预先分配一小块内存,也就是本地线程分配缓冲(Thread Local Allocation Buffer),分配内存时,先在本地线程分配缓存中进行内存的分配,用完了再用CAS来进行分配。(是否使用本地线程分配缓冲是通过 -XX: UseTLAB 参数来确定的 +开启 -关闭)
3)然后进行对象的创建 (一系列的赋值操作)
对象的内存布局
对象在内存中的分配布局分为:对象头、实例数据、对齐填充
对象头中分为两部分:一部分是 存储对象自身的信息:比如 哈希码、持有的锁、分代年龄、偏向线程等等。另一部分是存的类型指针,指向实例对应的类型。
浙公网安备 33010602011771号