线程局部缓冲区(TLAB)
若是无法在栈上分配,则工具会在堆上分配。对于 JDK1.8 来说,Java 堆通常使用分代模子,(关于 GC,垃圾接纳算法等这里不做详细讨论)。经由统计,90%的工具在使用完成后都市被接纳,因此默认新生代会分配 10%的空间给幸存者区。
工具先在 eden 区举行分配,然则我们知道,堆是所有线程共享的区域,会存在多线程并发问题。因此在堆上分配就需要举行线程同步。为了提高分配效率,JVM 会为每个线程从 eden 区初始化一块堆内存,该内存是线程私有的。这样每次分配工具时就无需举行同步操作,从而提高工具分配效率。线程的这块局部内存区域被称为线程局部缓冲区(TLAB)。通常这块内存会小于 eden 区的 1%。当这块内存用完时,就会重新通过 CAS 的方式为线程重新分配一块 TLAB。
通常工具分配有两种方式,一种是线性分配,当内存是规整时(大部门垃圾接纳器新生代都是用符号整理算法,可以保证内存规整),通过一个指针向后移动工具巨细,直接分配一块内存给工具,指针左边是已使用的内存,指针右边是未使用的内存,这种方式被称为指针碰撞。TLAB 配合指针碰撞手艺能够在线程平安的情形下移动一次指针直接就可以完成工具的内存分配。
当内存不规整时(好比 CMS 垃圾接纳器通常情形并不会每次 GC 后都压缩内存,会存在内存碎片),则需要一块分外的内存纪录哪些内存是空闲的,这个缓存被称为空闲列表。
eden 区分配
若是 TLAB 无法分配工具,那么工具只能在 Eden 区直接分配,前面说过,在堆上分配,必须接纳同步战略阻止有发生线程平安问题。若是分配内存时,工具的 klass 没有剖析过,则需要先举行类加载历程,然后才气分配工具。这个历程被称为慢速分配,而若是 klass 已剖析过则直接可以分配工具,这个历程被称为快速分配。
暮年月分配
当 eden 区放不下工具时(固然另有其他的判断战略,这里暂时不去体贴),工具直接分配到暮年月。