jvm是什么_解密new一个对象的过程中,JVM都做了什么?

面向对象

众所周知,Java是一门面向对象的高级编程语言,那么现在问题来了,对象从哪来呢?有些人会说通过new关键字来创建一个对象,说的很好,本篇我们就来解密在new一个对象的过程中,JVM都给我们做了什么工作。

d49341ee0c6582712d47d9f2afa87341.png

走哪来,到哪去

一个对象的诞生必定有一个类,通常我们都是通过new关键字实例化一个类来获取该类的一个对象,类在加载的过程中会经历一系列的检查,解析,初始化等一系列的过程,我们会在后面详细的分步骤进行讲解,这里我们只关心对象。

下面对象就要被加载到我们的虚拟机内存的堆内存中,加载到堆内存中也就意味着这个对象需要一定的空间,那么这个空间走哪来呢?这里JVM规范给出了两种情况:

指针碰撞

所谓指针碰撞,前提的条件是JVM的堆内存是绝对工整的,中间有一个指针作为分割空闲空间和已用空间的”三八线“,指针碰撞一般发生在Eden区,跟踪在Eden创建的最后一个对象,这个对象会被放在Eden的顶部。如果有足够的空间,对象就会被创建在Eden,并且被放置在顶部,然后将指针向上移动(如果你玩过俄罗斯方块,你就应该明白,说白了就是一种不可消除绝对规整的俄罗斯方块),当俄罗斯方块被堆满之后,就会触发一次Minor GC(关于GC的知识,我们在后面来讲解)

55d2c83ee92e5a622c997293a7da9d8a.png

打个比方来说,一个班里有很多座位,学生必须按照顺序来坐,这样只需要知道最后一个进来的学生坐哪就知道下一个学生坐哪,以及有没有空位~

78e668a68e11e907c0bec091d6fe8aeb.png

在单线程的情况下,我们这样使用是没有什么问题的,但是如果处于多线程并发的情况,就会出现分配空间失败的情况,打个比方来说,就是把一个位置同时卖给了两个人,这种情况势必就会打架,这种情况下,我们可以采取两种方法来解决这个问题:

  • 使用CAS+失败重试保证更新操作的原子性

CAS(Compare And Swap),关键是3个操作数。

内存值V

旧的预期值A

要修改的新值B

当且仅当预期值A和内存值V相同时,将内存值V修改为B,否则什么都不做。

736a298e284759224d010bc3e601d3e3.png
  • 第二种方法,结合我们上节课说到的TLAB来实现,在分配内存的时候在每个线程上的TLAB(Thread Local Allocation Buffer)区域进行分配,这里分配的时候可以初始化为零值,这一步操作保证了对象实例字段在Java代码中不赋值就可以直接使用。
c221183f0d0ce5f188531b6ef1f10c34.png

Free List

另一种情况是当堆内存不规整的情况下(学生不要排排坐),JVM会把没来上课的学生(未使用的内存)记到小本本上,当有新学生(新的对象)来上课的时候,可以去看本本上的座位图给学生安排座位~

9eb92ff0a51c7b718212d71de50ac239.png

end:如果你觉得本文对你有帮助的话,记得关注点赞转发,你的支持就是我更新动力。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值