「每日五分钟,玩转JVM」:对象从哪来

面向对象

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

走哪来,到哪去

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

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

指针碰撞

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

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

image-20190819215012007

在单线程的状况下,咱们这样使用是没有什么问题的,可是若是处于多线程并发的状况,就会出现分配空间失败的状况,打个比方来讲,就是把一个位置同时卖给了两我的,这种状况势必就会打架,这种状况下,咱们能够采起两种方法来解决这个问题:3d

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

CAS(Compare And Swap),关键是3个操做数。指针

内存值Vcdn

旧的预期值A对象

要修改的新值Bblog

当且仅当预期值A和内存值V相同时,将内存值V修改成B,不然什么都不作。

image-20190819222536824

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

    image-20190819223452177

Free List

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

这个JVM的小本本就叫作空闲列表(Free List)。

结语

到这里,对于虚拟机,对象就已经找到了本身的座位并落座,下一篇,咱们来介绍一下对象中都有什么。

公众号

相关文章
相关标签/搜索