JVM——对象的创建过程

对象的创建过程:

我们在Java代码中new 一个对象时,我们很难看到对象创建的过程,尤其是在jvm内存中的过程,下面来介绍一下对象创建在jvm中的过程:

    对象实例在jvm中是存在于java堆中的,每一个对象实例都会占用一定的内存空间,

    当new执行时,首先会加载new的类

    当类加载完成之后,实例对象所占的大小就确定了。

    此时,jvm会在java堆中为实例对象开辟一块内存空间,用于存储对象实例。并且设置对象属于哪个类、如何找到对象(指针或地址)、对象的哈希码、对象的GC分代年龄等信息,这些信息存储在对象头中,还进行了对象属性的零值初始化。

    此时对于虚拟机来说已经完成了创建对象,但是对于java程序来说才好刚刚开始,对象初始化的init方法还没有执行。但是此时虚拟机已经进行了对象得零值设置,所以即使不执行init方法,程序中也是可以正常是用对象实例的。

实例化对象过程中的注意事项以及方法:

jvm为实例对象分配空间主要有两种方法

        一:指针碰撞:这种方法是在java堆中,将已用内存和未用的内存分开成两部分,两部分内存之间放这一个指针作为分界点,当有新的实例对象需要分配内存空间时,指针向未用内存一侧移动相应大小的距离,将新的实例对象存储在该内存空间上。这种方式需要内存是规整的。

        二:空闲列表:这种方法分配空间是随机,每次分配内存空间都是从空闲的内存中选取一块分配给实例对象。那么就需要一个列表来存放这些空闲的内存空间地址,每当有实例对象需要空间,就从这个列表中选取出一块内存分配给实例对象。这种情况下内存是不规则的。

        两种方法的选择取决于内存的结构是否规整,而内存结构是否规整则取决于采用的垃圾回收器是否带有压缩整理功能。

        例如:Serial、ParNew等带有compact过程的收集器,就是带有压缩整理功能的

                    CMS这种基于Mark—Sweep算法的收集器就是没有压缩整理功能的

    有些时候,创建对象操作很频繁,这样就有可能导致指针刚刚分配好,还没来得及创建对象,就被另一个线程抢先,先占用了指针,这时候就会产生问题,解决这种问题主要有两种办法:

        一:对创建对象动作行为进行同步处理,这种同步处理实质是CAS配上失败重试的方式实现保证更新操作的原子性的。

        二:把每一个创建对象的动作行为按照线程划分为不同的空间中进行,这种方式就是将创建对象行为放入到线程中,为每一个线程分配一小块内存空间(TLAB),每个线程要分配内存就在自己的TLAB上运行分配,只有当TLAB满了,需要重新分配TLAB时,才需要进行同步锁定。

        TLAB方式的开启需要通过-XX:+/-UseTLAB参数设定。

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值