Java对象创建时的内存分配方式

       Java中通过new指令创建对象,当jvm收到一条new指令时,会首先检查常量池中是否可以定位到指定类的符号引用;如果可以,则表示对应类已经加载到jvm中,否则就需要先进行类加载的操作。

      类检查过程完成以后,会为新生的对象分配内存空间。对象所需的内存空间大小在类加载完成之后随即确定。对象内存空间分配的方式受堆空间是否规整影响,而堆空间是否规整决定于JVM采用的垃圾回收机制以及是否有压缩整理功能。

一、指针碰撞

       如果堆内存是规整的空间,即已经分配的内存与未使用的内存都是连续的空间,此时存在着一个指针位于已用与可用内存的分界,新内存的分配即指针移动对象大小的距离即可。此方式称为指针碰撞。
       由于堆空间是线程共享的,所以该方式存在着并发问题,通常有以下两种解决方案:
           1. 对内存分配的动作进行同步处理;
           2. 本地线程分配缓冲(LTAB)。
           ###本地线程分配缓冲:将内存按照分配的动作按线程划分在不同的空间进行,即每个线程在Java堆中预先申请一块内存(LTAB),哪个线程需要分配空间,就在哪个线程的LTAB上执行。只有当某一线程的LTAB用完了才执行同步锁定。

二、空闲列表

      如果堆空间中已分配的内存与未分配的内存相互交错,就需要使用“空闲列表”的方式进行内存分配操作。此时堆内存中维护了一份可用内存的列表,当有新内存分配的需求时,会到空闲列表中确定足够大小的内存空间予以分配操作。

      内存空间分配完毕以后会对内存空间进行初始化操作,如果使用LTAB,该操作也可以提前到LTAB分配时执行。这也是为什么类变量具有默认初始化的原因。

猜你喜欢

转载自blog.csdn.net/qq_29468573/article/details/82888466